diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt
index 3251d2c62..06ab0fa65 100644
--- a/deps/CMakeLists.txt
+++ b/deps/CMakeLists.txt
@@ -152,6 +152,9 @@ include(MPFR/MPFR.cmake)
 include(CGAL/CGAL.cmake)
 include(wxWidgets/wxWidgets.cmake)
 
+add_dependencies(dep_blosc ${ZLIB_PKG})
+add_dependencies(dep_openexr ${ZLIB_PKG})
+
 if (MSVC)
 
     add_custom_target(deps ALL
diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake
index 8be9888bc..ac93b4932 100644
--- a/deps/deps-windows.cmake
+++ b/deps/deps-windows.cmake
@@ -35,8 +35,6 @@ else ()
     set(DEP_PLATFORM "x64")
 endif ()
 
-
-
 if (${DEP_DEBUG})
     set(DEP_BOOST_DEBUG "debug")
 else ()
@@ -217,7 +215,6 @@ ExternalProject_Add(dep_blosc
     #URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9
     GIT_REPOSITORY https://github.com/Blosc/c-blosc.git
     GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0
-    DEPENDS ${ZLIB_PKG}
     CMAKE_GENERATOR "${DEP_MSVC_GEN}"
     CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
     CMAKE_ARGS
@@ -243,8 +240,7 @@ add_debug_dep(dep_blosc)
 ExternalProject_Add(dep_openexr
     EXCLUDE_FROM_ALL 1
     GIT_REPOSITORY https://github.com/openexr/openexr.git
-    GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0 
-    DEPENDS ${ZLIB_PKG}
+    GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0
     CMAKE_GENERATOR "${DEP_MSVC_GEN}"
     CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
     CMAKE_ARGS
diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h
index c425bbef2..eb47459ea 100644
--- a/src/imgui/imconfig.h
+++ b/src/imgui/imconfig.h
@@ -107,6 +107,13 @@ namespace ImGui
     const char ColorMarkerStart = 0x2; // STX
     const char ColorMarkerEnd   = 0x3; // ETX
 
+    // Special ASCII characters are used here as a ikons markers 
+    const char PrintIconMarker      = 0x4; 
+    const char PrinterIconMarker    = 0x5; 
+    const char PrinterSlaIconMarker = 0x6; 
+    const char FilamentIconMarker   = 0x7; 
+    const char MaterialIconMarker   = 0x8;
+
 //    void MyFunction(const char* name, const MyMatrix44& v);
 
 }
diff --git a/src/libslic3r/Fill/FillRectilinear2.cpp b/src/libslic3r/Fill/FillRectilinear2.cpp
index b88520b55..d83249939 100644
--- a/src/libslic3r/Fill/FillRectilinear2.cpp
+++ b/src/libslic3r/Fill/FillRectilinear2.cpp
@@ -1361,7 +1361,6 @@ static void traverse_graph_generate_polylines(
                 continue;
             }
 
-        dont_connect:
             // No way to continue the current polyline. Take the rest of the line up to the outer contour.
             // This will finish the polyline, starting another polyline at a new point.
             going_up ? ++ it : -- it;
@@ -1442,6 +1441,8 @@ struct MonotonousRegionLink
     AntPath 			*next_flipped;
 };
 
+// Matrix of paths (AntPath) connecting ends of MontonousRegions.
+// AntPath lengths and their derived visibilities refer to the length of the perimeter line if such perimeter segment exists.
 class AntPathMatrix
 {
 public:
@@ -1456,6 +1457,12 @@ public:
 		// From end of one region to the start of another region, both flipped or not flipped.
 		m_matrix(regions.size() * regions.size() * 4, AntPath{ -1., -1., initial_pheromone}) {}
 
+	void update_inital_pheromone(float initial_pheromone)
+	{
+		for (AntPath &ap : m_matrix)
+			ap.pheromone = initial_pheromone;
+	}
+
 	AntPath& operator()(const MonotonousRegion &region_from, bool flipped_from, const MonotonousRegion &region_to, bool flipped_to)
 	{
 		int row = 2 * int(&region_from - m_regions.data()) + flipped_from;
@@ -1478,7 +1485,7 @@ public:
 				// Just apply the Eucledian distance of the end points.
 			    path.length = unscale<float>(Vec2f(vline_to.pos - vline_from.pos, vline_to.intersections[i_to].pos() - vline_from.intersections[i_from].pos()).norm());
 			}
-			path.visibility = 1. / (path.length + EPSILON);
+			path.visibility = 1.f / (path.length + float(EPSILON));
 		}
 		return path;
 	}
@@ -1497,7 +1504,7 @@ private:
 	const ExPolygonWithOffset 						&m_poly_with_offset;
 	const std::vector<SegmentedIntersectionLine> 	&m_segs;
 	// From end of one region to the start of another region, both flipped or not flipped.
-	//FIXME one may possibly use sparse representation of the matrix.
+	//FIXME one may possibly use sparse representation of the matrix, likely using hashing.
 	std::vector<AntPath>					         m_matrix;
 };
 
@@ -1724,7 +1731,98 @@ static std::vector<MonotonousRegion> generate_montonous_regions(std::vector<Segm
     return monotonous_regions;
 }
 
-static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, std::vector<SegmentedIntersectionLine> &segs)
+// Traverse path, calculate length of the draw for the purpose of optimization.
+// This function is very similar to polylines_from_paths() in the way how it traverses the path, but
+// polylines_from_paths() emits a path, while this function just calculates the path length.
+static float montonous_region_path_length(const MonotonousRegion &region, bool dir, const ExPolygonWithOffset &poly_with_offset, const std::vector<SegmentedIntersectionLine> &segs)
+{
+    // From the initial point (i_vline, i_intersection), follow a path.
+	int   i_intersection = region.left_intersection_point(dir);
+	int   i_vline 		 = region.left.vline;
+	float total_length   = 0.;
+	bool  no_perimeter   = false;
+	Vec2f last_point;
+
+	for (;;) {
+        const SegmentedIntersectionLine &vline 		= segs[i_vline];
+        const SegmentIntersection       *it    		= &vline.intersections[i_intersection];
+        const bool                       going_up   = it->is_low();
+
+        if (no_perimeter)
+        	total_length += (last_point - Vec2f(vline.pos, (it + (going_up ? - 1 : 1))->pos())).norm();
+
+        int iright = it->right_horizontal();
+        if (going_up) {
+            // Traverse the complete vertical segment up to the inner contour.
+            for (;;) {
+	            do {
+	                ++ it;
+					iright = std::max(iright, it->right_horizontal());
+                    assert(it->is_inner());
+                } while (it->type != SegmentIntersection::INNER_HIGH || (it + 1)->type != SegmentIntersection::OUTER_HIGH);
+	            int inext = it->vertical_up();
+                if (inext == -1 || it->vertical_up_quality() != SegmentIntersection::LinkQuality::Valid)
+	            	break;
+                assert(it->iContour == vline.intersections[inext].iContour);
+                it = vline.intersections.data() + inext;
+            } 
+        } else {
+            // Going down.
+            assert(it->is_high());
+            assert(i_intersection > 0);
+            for (;;) {
+	            do {
+	                -- it;
+	                if (int iright_new = it->right_horizontal(); iright_new != -1)
+	                	iright = iright_new;
+                    assert(it->is_inner());
+	            } while (it->type != SegmentIntersection::INNER_LOW || (it - 1)->type != SegmentIntersection::OUTER_LOW);
+	            int inext = it->vertical_down();
+	            if (inext == -1 || it->vertical_down_quality() != SegmentIntersection::LinkQuality::Valid)
+	            	break;
+                assert(it->iContour == vline.intersections[inext].iContour);
+                it = vline.intersections.data() + inext;
+            } 
+        }
+
+        if (i_vline == region.right.vline)
+        	break;
+
+        int inext = it->right_horizontal();
+        if (inext != -1 && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
+        	// Summarize length of the connection line along the perimeter.
+        	//FIXME should it be weighted with a lower weight than non-extruding connection line? What weight?
+        	// Taking half of the length.
+    		total_length += 0.5f * float(measure_perimeter_horizontal_segment_length(poly_with_offset, segs, i_vline, it - vline.intersections.data(), inext));
+			// Don't add distance to the next vertical line start to the total length.
+			no_perimeter   = false;
+            i_intersection = inext;
+        } else {
+	        // Finish the current vertical line,
+        	going_up ? ++ it : -- it;
+	        assert(it->is_outer());
+	        assert(it->is_high() == going_up);
+	        // Mark the end of this vertical line.
+			last_point = Vec2f(vline.pos, it->pos());
+			// Remember to add distance to the last point.
+			no_perimeter = true;
+			if (inext == -1) {
+				// Find the end of the next overlapping vertical segment.
+		        const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
+                const SegmentIntersection       *right       = going_up ? 
+                    &vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
+				i_intersection = int(right - vline_right.intersections.data());
+			} else
+	            i_intersection = inext;
+        }
+
+        ++ i_vline;
+    }
+
+    return unscale<float>(total_length);
+}
+
+static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, const ExPolygonWithOffset &poly_with_offset, std::vector<SegmentedIntersectionLine> &segs)
 {
 	// Map from low intersection to left / right side of a monotonous region.
 	using MapType = std::pair<SegmentIntersection*, MonotonousRegion*>;
@@ -1816,6 +1914,20 @@ static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, s
         }
     }
 #endif /* NDEBUG */
+
+    // Fill in sum length of connecting lines of a region. This length is used for optimizing the infill path for minimum length.
+    for (MonotonousRegion &region : regions) {
+    	region.len1 = montonous_region_path_length(region, false, poly_with_offset, segs);
+    	region.len2 = montonous_region_path_length(region, true,  poly_with_offset, segs);
+    	// Subtract the smaller length from the longer one, so we will optimize just with the positive difference of the two.
+    	if (region.len1 > region.len2) {
+    		region.len1 -= region.len2;
+    		region.len2 = 0;
+    	} else {
+    		region.len2 -= region.len1;
+    		region.len1 = 0;
+    	}
+    }
 }
 
 // Raad Salman: Algorithms for the Precedence Constrained Generalized Travelling Salesperson Problem
@@ -1851,6 +1963,7 @@ inline void print_ant(const std::string& fmt, TArgs&&... args) {
 }
 
 // Find a run through monotonous infill blocks using an 'Ant colony" optimization method.
+// http://www.scholarpedia.org/article/Ant_colony_optimization
 static std::vector<MonotonousRegionLink> chain_monotonous_regions(
 	std::vector<MonotonousRegion> &regions, const ExPolygonWithOffset &poly_with_offset, const std::vector<SegmentedIntersectionLine> &segs, std::mt19937_64 &rng)
 {
@@ -1940,14 +2053,18 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
         };
 #endif /* NDEBUG */
 
-	// How many times to repeat the ant simulation.
-	constexpr int num_rounds = 10;
+	// How many times to repeat the ant simulation (number of ant generations).
+	constexpr int   num_rounds = 25;
+	// After how many rounds without an improvement to exit?
+	constexpr int 	num_rounds_no_change_exit = 8;
 	// With how many ants each of the run will be performed?
-	constexpr int num_ants = 10;
-	// Base (initial) pheromone level.
-	constexpr float pheromone_initial_deposit = 0.5f;
+	const int   	num_ants = std::min<int>(regions.size(), 10);
+	// Base (initial) pheromone level. This value will be adjusted based on the length of the first greedy path found.
+	float           pheromone_initial_deposit = 0.5f;
 	// Evaporation rate of pheromones.
 	constexpr float pheromone_evaporation = 0.1f;
+    // Evaporation rate to diversify paths taken by individual ants.
+    constexpr float pheromone_diversification = 0.1f;
 	// Probability at which to take the next best path. Otherwise take the the path based on the cost distribution.
 	constexpr float probability_take_best = 0.9f;
 	// Exponents of the cost function.
@@ -1956,6 +2073,73 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
 
     AntPathMatrix path_matrix(regions, poly_with_offset, segs, pheromone_initial_deposit);
 
+    // Find an initial path in a greedy way, set the initial pheromone value to 10% of the cost of the greedy path.
+    {
+    	// Construct the first path in a greedy way to calculate an initial value of the pheromone value.
+		queue = queue_initial;
+		left_neighbors_unprocessed = left_neighbors_unprocessed_initial;
+        assert(validate_unprocessed());
+        // Pick the last of the queue.
+        MonotonousRegionLink path_end { queue.back(), false };
+        queue.pop_back();
+        -- left_neighbors_unprocessed[path_end.region - regions.data()];
+
+        float total_length = path_end.region->length(false);
+		while (! queue.empty() || ! path_end.region->right_neighbors.empty()) {
+            // Chain.
+			MonotonousRegion 		    &region = *path_end.region;
+			bool 			  			 dir    = path_end.flipped;
+			NextCandidate 				 next_candidate;
+			next_candidate.probability = 0;
+			for (MonotonousRegion *next : region.right_neighbors) {
+				int &unprocessed = left_neighbors_unprocessed[next - regions.data()];
+				assert(unprocessed > 1);
+				if (left_neighbors_unprocessed[next - regions.data()] == 2) {
+					// Dependencies of the successive blocks are satisfied.
+                    AntPath &path1 = path_matrix(region, dir, *next, false);
+                    AntPath &path2 = path_matrix(region, dir, *next, true);
+                    if (path1.visibility > next_candidate.probability)
+                        next_candidate = { next, &path1, &path1, path1.visibility, false };
+	                if (path2.visibility > next_candidate.probability)
+                        next_candidate = { next, &path2, &path2, path2.visibility, true  };
+				}
+			}
+			bool from_queue = next_candidate.probability == 0;
+            if (from_queue) {
+                for (MonotonousRegion *next : queue) {
+                    AntPath &path1 = path_matrix(region, dir, *next, false);
+                    AntPath &path2 = path_matrix(region, dir, *next, true);
+                    if (path1.visibility > next_candidate.probability)
+                        next_candidate = { next, &path1, &path1, path1.visibility, false };
+	                if (path2.visibility > next_candidate.probability)
+                        next_candidate = { next, &path2, &path2, path2.visibility, true  };
+                }
+            }
+            // Move the other right neighbors with satisified constraints to the queue.
+			for (MonotonousRegion *next : region.right_neighbors)
+				if (-- left_neighbors_unprocessed[next - regions.data()] == 1 && next_candidate.region != next)
+	                queue.emplace_back(next);
+            if (from_queue) {
+                // Remove the selected path from the queue.
+                auto it = std::find(queue.begin(), queue.end(), next_candidate.region);
+                assert(it != queue.end());
+                *it = queue.back();
+                queue.pop_back();
+            }
+			// Extend the path.
+			MonotonousRegion *next_region = next_candidate.region;
+			bool              next_dir    = next_candidate.dir;
+            total_length += next_region->length(next_dir) + path_matrix(*path_end.region, path_end.flipped, *next_region, next_dir).length;
+            path_end = { next_region, next_dir };
+            assert(left_neighbors_unprocessed[next_region - regions.data()] == 1);
+            left_neighbors_unprocessed[next_region - regions.data()] = 0;          
+        }
+
+        // Set an initial pheromone value to 10% of the greedy path's value.
+        pheromone_initial_deposit = 0.1 / total_length;
+        path_matrix.update_inital_pheromone(pheromone_initial_deposit);
+    }
+
     // Probability (unnormalized) of traversing a link between two monotonous regions.
 	auto path_probability = [pheromone_alpha, pheromone_beta](AntPath &path) {
 		return pow(path.pheromone, pheromone_alpha) * pow(path.visibility, pheromone_beta);
@@ -1966,8 +2150,10 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
     ++ irun;
 #endif /* SLIC3R_DEBUG_ANTS */
 
-    for (int round = 0; round < num_rounds; ++ round)
+    int num_rounds_no_change = 0;
+    for (int round = 0; round < num_rounds && num_rounds_no_change < num_rounds_no_change_exit; ++ round)
 	{
+		bool improved = false;
 		for (int ant = 0; ant < num_ants; ++ ant) 
 		{
 			// Find a new path following the pheromones deposited by the previous ants.
@@ -1977,6 +2163,8 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
 			left_neighbors_unprocessed = left_neighbors_unprocessed_initial;
             assert(validate_unprocessed());
             // Pick randomly the first from the queue at random orientation.
+            //FIXME picking the 1st monotonous region should likely be done based on accumulated pheromone level as well,
+            // but the inefficiency caused by the random pick of the 1st monotonous region is likely insignificant.
             int first_idx = std::uniform_int_distribution<>(0, int(queue.size()) - 1)(rng);
             path.emplace_back(MonotonousRegionLink{ queue[first_idx], rng() > rng.max() / 2 });
             *(queue.begin() + first_idx) = std::move(queue.back());
@@ -2051,7 +2239,7 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
                 for (std::vector<NextCandidate>::iterator it_next_candidate = next_candidates.begin(); it_next_candidate != next_candidates.begin() + num_direct_neighbors; ++ it_next_candidate)
                     if ((queue.empty() || it_next_candidate->region != queue.back()) && it_next_candidate->region != take_path->region)
                         queue.emplace_back(it_next_candidate->region);
-                if (take_path - next_candidates.begin() >= num_direct_neighbors) {
+                if (size_t(take_path - next_candidates.begin()) >= num_direct_neighbors) {
                     // Remove the selected path from the queue.
                     auto it = std::find(queue.begin(), queue.end(), take_path->region);
                     assert(it != queue.end());
@@ -2083,8 +2271,10 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
                     path.back().flipped == path.back().region->flips ? path.back().region->right.high : path.back().region->right.low,
                     path.back().flipped == path.back().region->flips ? path.back().region->right.low : path.back().region->right.high);
 
-				// Update pheromones along this link.
-				take_path->link->pheromone = (1.f - pheromone_evaporation) * take_path->link->pheromone + pheromone_evaporation * pheromone_initial_deposit;
+				// Update pheromones along this link, see Ant Colony System (ACS) update rule.
+				// http://www.scholarpedia.org/article/Ant_colony_optimization
+				// The goal here is to lower the pheromone trace for paths taken to diversify the next path picked in the same batch of ants.
+				take_path->link->pheromone = (1.f - pheromone_diversification) * take_path->link->pheromone + pheromone_diversification * pheromone_initial_deposit;
                 assert(validate_unprocessed());
             }
 
@@ -2104,18 +2294,33 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
 			if (path_length < best_path_length) {
 				best_path_length = path_length;
 				std::swap(best_path, path);
+#if 0 // #if ! defined(SLIC3R_DEBUG_ANTS) && ! defined(ndebug)
+				if (round == 0 && ant == 0)
+					std::cout << std::endl;
+			    std::cout << Slic3r::format("round %1% ant %2% path length %3%", round, ant, path_length) << std::endl;
+#endif
+                if (path_length == 0)
+                    // Perfect path found.
+                    goto end;
+                improved = true;
 			}
 		}
 
-		// Reinforce the path feromones with the best path.
-        float total_cost = best_path_length + EPSILON;
+		// Reinforce the path pheromones with the best path.
+        float total_cost = best_path_length + float(EPSILON);
         for (size_t i = 0; i + 1 < path.size(); ++ i) {
             MonotonousRegionLink &link = path[i];
             link.next->pheromone = (1.f - pheromone_evaporation) * link.next->pheromone + pheromone_evaporation / total_cost;
         }
+
+        if (improved)
+            num_rounds_no_change = 0;
+        else
+			++ num_rounds_no_change;
 	}
 
-	return best_path;
+end:
+    return best_path;
 }
 
 // Traverse path, produce polylines.
@@ -2195,7 +2400,6 @@ static void polylines_from_paths(const std::vector<MonotonousRegionLink> &path,
 		            int inext = it->vertical_up();
                     if (inext == -1 || it->vertical_up_quality() != SegmentIntersection::LinkQuality::Valid)
 		            	break;
-		            const Polygon &poly = poly_with_offset.contour(it->iContour);
 	                assert(it->iContour == vline.intersections[inext].iContour);
 	                emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_left_vertical_up());
 	                it = vline.intersections.data() + inext;
@@ -2215,7 +2419,6 @@ static void polylines_from_paths(const std::vector<MonotonousRegionLink> &path,
 		            int inext = it->vertical_down();
 		            if (inext == -1 || it->vertical_down_quality() != SegmentIntersection::LinkQuality::Valid)
 		            	break;
-		            const Polygon &poly = poly_with_offset.contour(it->iContour);
 	                assert(it->iContour == vline.intersections[inext].iContour);
 	                emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_right_vertical_down());
 	                it = vline.intersections.data() + inext;
@@ -2285,8 +2488,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
     ExPolygonWithOffset poly_with_offset(
         surface->expolygon, 
         - rotate_vector.first, 
-        scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
-        scale_(this->overlap - 0.5 * this->spacing));
+        float(scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing)),
+        float(scale_(this->overlap - 0.5 * this->spacing)));
     if (poly_with_offset.n_contours_inner == 0) {
         // Not a single infill line fits.
         //FIXME maybe one shall trigger the gap fill here?
@@ -2317,7 +2520,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
     size_t  n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
 	coord_t x0 = bounding_box.min(0);
 	if (params.full_infill())
-		x0 += (line_spacing + SCALED_EPSILON) / 2;
+		x0 += (line_spacing + coord_t(SCALED_EPSILON)) / 2;
 
 #ifdef SLIC3R_DEBUG
     static int iRun = 0;
@@ -2359,7 +2562,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
     bool monotonous_infill = params.monotonous; // || params.density > 0.99;
     if (monotonous_infill) {
 		std::vector<MonotonousRegion> regions = generate_montonous_regions(segs);
-		connect_monotonous_regions(regions, segs);
+		connect_monotonous_regions(regions, poly_with_offset, segs);
         if (! regions.empty()) {
 		    std::mt19937_64 rng;
 		    std::vector<MonotonousRegionLink> path = chain_monotonous_regions(regions, poly_with_offset, segs, rng);
@@ -2478,10 +2681,10 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams &para
     params3.dont_connect = true;
     Polylines polylines_out;
     coordf_t dx = sqrt(0.5) * z;
-    if (! fill_surface_by_lines(surface, params2, 0.f, dx, polylines_out) ||
-        ! fill_surface_by_lines(surface, params2, float(M_PI / 3.), - dx, polylines_out) ||
+    if (! fill_surface_by_lines(surface, params2, 0.f, float(dx), polylines_out) ||
+        ! fill_surface_by_lines(surface, params2, float(M_PI / 3.), - float(dx), polylines_out) ||
         // Rotated by PI*2/3 + PI to achieve reverse sloping wall.
-        ! fill_surface_by_lines(surface, params3, float(M_PI * 2. / 3.), dx, polylines_out)) {
+        ! fill_surface_by_lines(surface, params3, float(M_PI * 2. / 3.), float(dx), polylines_out)) {
         printf("FillCubic::fill_surface() failed to fill a region.\n");
     } 
     return polylines_out; 
diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp
index 58b15e9a4..8aec327db 100644
--- a/src/libslic3r/GCode/PreviewData.cpp
+++ b/src/libslic3r/GCode/PreviewData.cpp
@@ -119,7 +119,8 @@ const Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[erCount]
     Color(1.0f, 1.0f, 0.0f, 1.0f),   // erInternalInfill
     Color(1.0f, 0.0f, 1.0f, 1.0f),   // erSolidInfill
     Color(0.0f, 1.0f, 1.0f, 1.0f),   // erTopSolidInfill
-    Color(0.0f, 1.0f, 1.0f, 1.0f),   // erIroning    
+//    Color(1.0f, 0.7f, 0.61f, 1.0f),   // erIroning
+    Color(1.0f, 0.55f, 0.41f, 1.0f),   // erIroning
     Color(0.5f, 0.5f, 0.5f, 1.0f),   // erBridgeInfill
     Color(1.0f, 1.0f, 1.0f, 1.0f),   // erGapFill
     Color(0.5f, 0.0f, 0.0f, 1.0f),   // erSkirt
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index d291be36c..fefc12ba8 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -218,6 +218,12 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
     target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES}) 
 endif()
 
+if (SLIC3R_STATIC)
+    # FIXME: This was previously exported by wx-config but the wxWidgets
+    # cmake build forgets this and the build fails in debug mode (or on raspberry release)
+    target_compile_definitions(libslic3r_gui PUBLIC -DwxDEBUG_LEVEL=0)
+endif()
+
 if(APPLE)
     target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY})
 endif()
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 8be8f8b37..259b0c03b 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -4323,6 +4323,9 @@ void GLCanvas3D::update_ui_from_settings()
         _refresh_if_shown_on_screen();
     }
 #endif // ENABLE_RETINA_GL
+
+    bool enable_collapse = wxGetApp().app_config->get("show_collapse_button") == "1";
+    enable_collapse_toolbar(enable_collapse);
 }
 
 
@@ -4376,6 +4379,16 @@ void GLCanvas3D::msw_rescale()
     m_warning_texture.msw_rescale(*this);
 }
 
+void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar()
+{
+    std::string new_tooltip = _u8L("Switch to Settings") + 
+                             "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab")    + 
+                             "\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
+                             "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
+
+    m_main_toolbar.set_tooltip(get_main_toolbar_item_id("settings"), new_tooltip);
+}
+
 bool GLCanvas3D::has_toolpaths_to_export() const
 {
     return m_volumes.has_toolpaths_to_export();
@@ -5003,10 +5016,26 @@ bool GLCanvas3D::_init_main_toolbar()
     if (!m_main_toolbar.add_separator())
         return false;
 
+    item.name = "settings";
+    item.icon_filename = "cog.svg";
+    item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab")    + 
+                                                "\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
+                                                "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
+    item.sprite_id = 10;
+    item.enabling_callback    = GLToolbarItem::Default_Enabling_Callback;
+    item.visibility_callback  = [this]() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" ||
+                                                   wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); };
+    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(); };
+    if (!m_main_toolbar.add_item(item))
+        return false;
+
+    if (!m_main_toolbar.add_separator())
+        return false;
+
     item.name = "layersediting";
     item.icon_filename = "layers_white.svg";
     item.tooltip = _utf8(L("Variable layer height"));
-    item.sprite_id = 10;
+    item.sprite_id = 11;
     item.left.toggable = true;
     item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
     item.visibility_callback = [this]()->bool
@@ -5028,7 +5057,7 @@ bool GLCanvas3D::_init_main_toolbar()
     item.name = "search";
     item.icon_filename = "search_.svg";
     item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]";
-    item.sprite_id = 11;
+    item.sprite_id = 12;
     item.left.render_callback = [this](float left, float right, float, float) {
         if (m_canvas != nullptr)
         {
@@ -5164,7 +5193,7 @@ bool GLCanvas3D::_init_view_toolbar()
 
 bool GLCanvas3D::_init_collapse_toolbar()
 {
-    if (!m_collapse_toolbar.is_enabled())
+    if (!m_collapse_toolbar.is_enabled() && m_collapse_toolbar.get_items_count() > 0)
         return true;
 
     BackgroundTexture::Metadata background_data;
@@ -5205,61 +5234,10 @@ bool GLCanvas3D::_init_collapse_toolbar()
         wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed());
     };
 
-    if (!m_collapse_toolbar.add_item(item))
-        return false;
-
-    if (!m_collapse_toolbar.add_separator())
-        return false;
-
-    item.name = "print";
-    item.icon_filename = "cog.svg";
-    item.tooltip = _utf8(L("Switch to Print Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "2]";
-    item.sprite_id = 1;
-    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*0*/1); };
-
-    if (!m_collapse_toolbar.add_item(item))
-        return false;
-
-    item.name = "filament";
-    item.icon_filename = "spool.svg";
-    item.tooltip = _utf8(L("Switch to Filament Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
-    item.sprite_id = 2;
-    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
-    item.visibility_callback  = [this]() { return wxGetApp().plater()->printer_technology() == ptFFF; };
-
-    if (!m_collapse_toolbar.add_item(item))
-        return false;
-
-    item.name = "printer";
-    item.icon_filename = "printer.svg";
-    item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
-    item.sprite_id = 3;
-    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
-
-    if (!m_collapse_toolbar.add_item(item))
-        return false;
-
-    item.name = "resin";
-    item.icon_filename = "resin.svg";
-    item.tooltip = _utf8(L("Switch to SLA Material Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
-    item.sprite_id = 4;
-    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
-    item.visibility_callback  = [this]() { return m_process->current_printer_technology() == ptSLA; };
-
-    if (!m_collapse_toolbar.add_item(item))
-        return false;
-
-    item.name = "sla_printer";
-    item.icon_filename = "sla_printer.svg";
-    item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
-    item.sprite_id = 5;
-    item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
-
     if (!m_collapse_toolbar.add_item(item))
         return false;
 
     return true;
-
 }
 
 bool GLCanvas3D::_set_current()
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 5684901f3..cc43e7d14 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -739,6 +739,7 @@ public:
     int get_main_toolbar_item_id(const std::string& name) const { return m_main_toolbar.get_item_id(name); }
     void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); }
     void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); }
+    void update_tooltip_for_settings_item_in_main_toolbar();
 
     bool has_toolpaths_to_export() const;
     void export_toolpaths_to_obj(const char* filename) const;
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 0d437958c..e7f784773 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -247,7 +247,7 @@ bool GLToolbar::is_enabled() const
 
 void GLToolbar::set_enabled(bool enable)
 {
-    m_enabled = true;
+    m_enabled = enable;//true; etFIXME
 }
 
 bool GLToolbar::add_item(const GLToolbarItem::Data& data)
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 5e4f85e87..dcef48de9 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -412,7 +412,8 @@ bool GUI_App::on_init_inner()
     if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
         wxImage::AddHandler(new wxPNGHandler());
     mainframe = new MainFrame();
-    mainframe->switch_to(true); // hide settings tabs after first Layout
+    // hide settings tabs after first Layout
+    mainframe->select_tab(0);
 
     sidebar().obj_list()->init_objects(); // propagate model objects to object list
 //     update_mode(); // !!! do that later
@@ -601,6 +602,8 @@ void GUI_App::recreate_GUI()
 
     MainFrame *old_main_frame = mainframe;
     mainframe = new MainFrame();
+    // hide settings tabs after first Layout
+    mainframe->select_tab(0);
     // Propagate model objects to object list.
     sidebar().obj_list()->init_objects();
     SetTopWindow(mainframe);
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index ea8b2afd3..4385fa276 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -7,6 +7,7 @@
 
 #include <boost/format.hpp>
 #include <boost/log/trivial.hpp>
+#include <boost/filesystem.hpp>
 
 #include <wx/string.h>
 #include <wx/event.h>
@@ -27,10 +28,22 @@
 #include "I18N.hpp"
 #include "Search.hpp"
 
+#include "../Utils/MacDarkMode.hpp"
+#include "nanosvg/nanosvg.h"
+#include "nanosvg/nanosvgrast.h"
+
 namespace Slic3r {
 namespace GUI {
 
 
+static const std::map<const char, std::string> font_icons = {
+    {ImGui::PrintIconMarker     , "cog"        },
+    {ImGui::PrinterIconMarker   , "printer"    },
+    {ImGui::PrinterSlaIconMarker, "sla_printer"},
+    {ImGui::FilamentIconMarker  , "spool"      },
+    {ImGui::MaterialIconMarker  , "resin"      }
+};
+
 ImGuiWrapper::ImGuiWrapper()
     : m_glyph_ranges(nullptr)
     , m_font_cjk(false)
@@ -735,9 +748,9 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
 
     // add checkboxes for show/hide Categories and Groups
     text(_L("Use for search")+":");
-    check_box(_L("Type"),       view_params.type);
     check_box(_L("Category"),   view_params.category);
     check_box(_L("Group"),      view_params.group);
+    check_box(_L("Search in English"), view_params.english);
 }
 
 void ImGuiWrapper::disabled_begin(bool disabled)
@@ -791,6 +804,59 @@ static const ImWchar ranges_keyboard_shortcuts[] =
 };
 #endif // __APPLE__
 
+
+std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height)
+{
+#ifdef __APPLE__
+    // Note: win->GetContentScaleFactor() is not used anymore here because it tends to
+    // return bogus results quite often (such as 1.0 on Retina or even 0.0).
+    // We're using the max scaling factor across all screens because it's very likely to be good enough.
+    double	scale = mac_max_scaling_factor();
+#else
+    double	scale = 1.0;
+#endif
+    std::vector<unsigned char> empty_vector;
+
+#ifdef __WXMSW__
+    std::string folder = "white\\";
+#else
+    std::string folder = "white/";
+#endif        
+    if (!boost::filesystem::exists(Slic3r::var(folder + bitmap_name + ".svg")))
+        folder.clear();
+
+    NSVGimage* image = ::nsvgParseFromFile(Slic3r::var(folder + bitmap_name + ".svg").c_str(), "px", 96.0f);
+    if (image == nullptr)
+        return empty_vector;
+
+    target_height != 0 ? target_height *= scale : target_width *= scale;
+
+    float svg_scale = target_height != 0 ?
+        (float)target_height / image->height : target_width != 0 ?
+        (float)target_width / image->width : 1;
+
+    int   width = (int)(svg_scale * image->width + 0.5f);
+    int   height = (int)(svg_scale * image->height + 0.5f);
+    int   n_pixels = width * height;
+    if (n_pixels <= 0) {
+        ::nsvgDelete(image);
+        return empty_vector;
+    }
+
+    NSVGrasterizer* rast = ::nsvgCreateRasterizer();
+    if (rast == nullptr) {
+        ::nsvgDelete(image);
+        return empty_vector;
+    }
+
+    std::vector<unsigned char> data(n_pixels * 4, 0);
+    ::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4);
+    ::nsvgDeleteRasterizer(rast);
+    ::nsvgDelete(image);
+
+    return data;
+}
+
 void ImGuiWrapper::init_font(bool compress)
 {
     destroy_font();
@@ -829,11 +895,33 @@ void ImGuiWrapper::init_font(bool compress)
     }
 #endif
 
+    float font_scale = m_font_size/15;
+    int icon_sz = lround(16 * font_scale); // default size of icon is 16 px
+
+    int rect_id = io.Fonts->CustomRects.Size;  // id of the rectangle added next
+    // add rectangles for the icons to the font atlas
+    for (auto& icon : font_icons)
+        io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
+
     // Build texture atlas
     unsigned char* pixels;
     int width, height;
     io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);   // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
 
+    // Fill rectangles from the SVG-icons
+    for (auto icon : font_icons) {
+        if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
+            std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
+            const ImU32* pIn = (ImU32*)raw_data.data();
+            for (int y = 0; y < icon_sz; y++) {
+                ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X);
+                for (int x = 0; x < icon_sz; x++)
+                    *pOut++ = *pIn++;
+            }
+        }
+        rect_id++;
+    }
+
     // Upload texture to graphics system
     GLint last_texture;
     glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp
index 6a1e27dcb..efb8acc9a 100644
--- a/src/slic3r/GUI/ImGuiWrapper.hpp
+++ b/src/slic3r/GUI/ImGuiWrapper.hpp
@@ -96,6 +96,7 @@ private:
     void render_draw_data(ImDrawData *draw_data);
     bool display_initialized() const;
     void destroy_font();
+    std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height);
 
     static const char* clipboard_get(void* user_data);
     static void clipboard_set(void* user_data, const char* text);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index dd39f86d1..62fffc423 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -90,10 +90,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
 
     // initialize layout
     auto sizer = new wxBoxSizer(wxVERTICAL);
-    if (m_plater)
+    if (m_plater && m_layout != slOld)
         sizer->Add(m_plater, 1, wxEXPAND);
-    if (m_tabpanel)
+
+    if (m_tabpanel && m_layout != slDlg)
         sizer->Add(m_tabpanel, 1, wxEXPAND);
+
     sizer->SetSizeHints(this);
     SetSizer(sizer);
     Fit();
@@ -227,6 +229,9 @@ void MainFrame::shutdown()
     // In addition, there were some crashes due to the Paint events sent to already destructed windows.
     this->Show(false);
 
+    if (m_settings_dialog)
+        m_settings_dialog->Destroy();
+
 	// Stop the background thread (Windows and Linux).
 	// Disconnect from a 3DConnextion driver (OSX).
     m_plater->get_mouse3d_controller().shutdown();
@@ -284,12 +289,25 @@ void MainFrame::update_title()
 
 void MainFrame::init_tabpanel()
 {
-    // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
-    // with multiple high resolution displays connected.
-    m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
+    m_layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? slOld :
+               wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? slNew :
+               wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? slDlg : slOld;
+
+    // From the very beginning the Print settings should be selected
+    m_last_selected_tab = m_layout == slDlg ? 0 : 1;
+
+    if (m_layout == slDlg) {
+        m_settings_dialog = new SettingsDialog(this);
+        m_tabpanel = m_settings_dialog->get_tabpanel();
+    }
+    else {
+        // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
+        // with multiple high resolution displays connected.
+        m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
 #ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
-    m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+        m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
 #endif
+    }
 
     m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
         auto panel = m_tabpanel->GetCurrentPage();
@@ -302,17 +320,22 @@ void MainFrame::init_tabpanel()
             // On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered
             // before the MainFrame is fully set up.
             static_cast<Tab*>(panel)->OnActivate();
+            m_last_selected_tab = m_tabpanel->GetSelection();
         }
         else
             select_tab(0);
     });
 
-//!    m_plater = new Slic3r::GUI::Plater(m_tabpanel, this);
-    m_plater = new Plater(this, this);
-
+    if (m_layout == slOld) {
+        m_plater = new Plater(m_tabpanel, this);
+        m_tabpanel->AddPage(m_plater, _L("Plater"));
+    }
+    else {
+        m_plater = new Plater(this, this);
+        if (m_layout == slNew)
+            m_tabpanel->AddPage(new wxPanel(m_tabpanel), _L("Plater")); // empty panel just for Plater tab
+    }
     wxGetApp().plater_ = m_plater;
-//    m_tabpanel->AddPage(m_plater, _(L("Plater")));
-    m_tabpanel->AddPage(new wxPanel(m_tabpanel), _L("Plater")); // empty panel just for Plater tab
 
     wxGetApp().obj_list()->create_popup_menus();
 
@@ -338,13 +361,6 @@ void MainFrame::init_tabpanel()
     }
 }
 
-void MainFrame::switch_to(bool plater)
-{
-    this->m_plater->Show(plater);
-    this->m_tabpanel->Show(!plater);
-    this->Layout();
-}
-
 void MainFrame::create_preset_tabs()
 {
     wxGetApp().update_label_colours_from_appconfig();
@@ -460,6 +476,11 @@ bool MainFrame::can_slice() const
 
 bool MainFrame::can_change_view() const
 {
+    if (m_layout == slNew)
+        return m_plater->IsShown();
+    if (m_layout == slDlg)
+        return true;
+    // slOld layout mode
     int page_id = m_tabpanel->GetSelection();
     return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr;
 }
@@ -758,25 +779,21 @@ void MainFrame::init_menubar()
     // Window menu
     auto windowMenu = new wxMenu();
     {
-//!        size_t tab_offset = 0;
         if (m_plater) {
             append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")),
-                [this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*(size_t)(-1)*/0); }, "plater", nullptr,
+                [this](wxCommandEvent&) { select_tab(0); }, "plater", nullptr,
                 [this]() {return true; }, this);
-//!            tab_offset += 1;
-//!        }
-//!        if (tab_offset > 0) {
             windowMenu->AppendSeparator();
         }
         append_menu_item(windowMenu, wxID_HIGHEST + 2, _(L("P&rint Settings Tab")) + "\tCtrl+2", _(L("Show the print settings")),
-            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 0*/1); }, "cog", nullptr,
+            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(1); }, "cog", nullptr,
             [this]() {return true; }, this);
         wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 3, _(L("&Filament Settings Tab")) + "\tCtrl+3", _(L("Show the filament settings")),
-            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 1*/2); }, "spool", nullptr,
+            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(2); }, "spool", nullptr,
             [this]() {return true; }, this);
         m_changeable_menu_items.push_back(item_material_tab);
         wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")),
-            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 2*/3); }, "printer", nullptr,
+            [this/*, tab_offset*/](wxCommandEvent&) { select_tab(3); }, "printer", nullptr,
             [this]() {return true; }, this);
         m_changeable_menu_items.push_back(item_printer_tab);
         if (m_plater) {
@@ -1240,17 +1257,28 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
 #endif
 }
 
-void MainFrame::select_tab(size_t tab)
+void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
 {
-    if (tab == /*(size_t)(-1)*/0) {
-        if (m_plater && !m_plater->IsShown())
-            this->switch_to(true);
+    if (m_layout == slDlg) {
+        if (tab==0) {
+            if (m_settings_dialog->IsShown())
+                this->SetFocus();
+            return;
+        }
+        // Show/Activate Settings Dialog
+        if (m_settings_dialog->IsShown())
+            m_settings_dialog->SetFocus();
+        else
+            m_settings_dialog->Show();
     }
-    else {
-        if (m_plater && m_plater->IsShown())
-            switch_to(false);
-        m_tabpanel->SetSelection(tab);
+    else if (m_layout == slNew) {
+        m_plater->Show(tab == 0);
+        m_tabpanel->Show(tab != 0);
+        Layout();
     }
+
+    // when tab == -1, it means we should to show the last selected tab 
+    m_tabpanel->SetSelection(tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == slDlg && tab != 0) ? tab-1 : tab);
 }
 
 // Set a camera direction, zoom to all objects.
@@ -1355,5 +1383,79 @@ std::string MainFrame::get_dir_name(const wxString &full_name) const
     return boost::filesystem::path(full_name.wx_str()).parent_path().string();
 }
 
+
+// ----------------------------------------------------------------------------
+// SettingsDialog
+// ----------------------------------------------------------------------------
+
+SettingsDialog::SettingsDialog(MainFrame* mainframe)
+: DPIDialog(nullptr, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Settings")),
+    m_main_frame(mainframe)
+{
+    this->SetFont(wxGetApp().normal_font());
+
+    wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+    this->SetBackgroundColour(bgr_clr);
+
+    // Load the icon either from the exe, or from the ico file.
+#if _WIN32
+    {
+        TCHAR szExeFileName[MAX_PATH];
+        GetModuleFileName(nullptr, szExeFileName, MAX_PATH);
+        SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO));
+    }
+#else
+    SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG));
+#endif // _WIN32
+
+    // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
+    // with multiple high resolution displays connected.
+    m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
+#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
+    m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+#endif
+
+    m_tabpanel->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& evt) {
+        if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
+            switch (evt.GetKeyCode()) {
+            case '1': { m_main_frame->select_tab(0); break; }
+            case '2': { m_main_frame->select_tab(1); break; }
+            case '3': { m_main_frame->select_tab(2); break; }
+            case '4': { m_main_frame->select_tab(3); break; }
+            default:break;
+            }
+        }
+    });
+
+    // initialize layout
+    auto sizer = new wxBoxSizer(wxVERTICAL);
+    sizer->Add(m_tabpanel, 1, wxEXPAND);
+    sizer->SetSizeHints(this);
+    SetSizer(sizer);
+    Fit();
+
+    const wxSize min_size = wxSize(85 * em_unit(), 50 * em_unit());
+#ifdef __APPLE__
+    // Using SetMinSize() on Mac messes up the window position in some cases
+    // cf. https://groups.google.com/forum/#!topic/wx-users/yUKPBBfXWO0
+    SetSize(min_size);
+#else
+    SetMinSize(min_size);
+    SetSize(GetMinSize());
+#endif
+    Layout();
+}
+
+void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
+{
+    const int& em = em_unit();
+    const wxSize& size = wxSize(85 * em, 50 * em);
+
+    SetMinSize(size);
+    Fit();
+    Refresh();
+}
+
+
 } // GUI
 } // Slic3r
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index 8fc0ed1f2..219f68319 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -43,6 +43,23 @@ struct PresetTab {
     PrinterTechnology technology;
 };
 
+// ----------------------------------------------------------------------------
+// SettingsDialog
+// ----------------------------------------------------------------------------
+
+class SettingsDialog : public DPIDialog
+{
+    wxNotebook* m_tabpanel { nullptr };
+    MainFrame*  m_main_frame {nullptr };
+public:
+    SettingsDialog(MainFrame* mainframe);
+    ~SettingsDialog() {}
+    wxNotebook* get_tabpanel() { return m_tabpanel; }
+
+protected:
+    void on_dpi_changed(const wxRect& suggested_rect) override;
+};
+
 class MainFrame : public DPIFrame
 {
     bool        m_loaded {false};
@@ -57,6 +74,8 @@ class MainFrame : public DPIFrame
 
     PrintHostQueueDialog *m_printhost_queue_dlg;
 
+    size_t      m_last_selected_tab;
+
     std::string     get_base_name(const wxString &full_name, const char *extension = nullptr) const;
     std::string     get_dir_name(const wxString &full_name) const;
 
@@ -94,6 +113,12 @@ class MainFrame : public DPIFrame
 
     wxFileHistory m_recent_projects;
 
+    enum SettingsLayout {
+        slOld = 0,
+        slNew,
+        slDlg,
+    }               m_layout;
+
 protected:
     virtual void on_dpi_changed(const wxRect &suggested_rect);
 
@@ -109,7 +134,6 @@ public:
     void        update_title();
 
     void        init_tabpanel();
-    void        switch_to(bool plater);
     void        create_preset_tabs();
     void        add_created_tab(Tab* panel);
     void        init_menubar();
@@ -130,7 +154,9 @@ public:
     void        export_configbundle();
     void        load_configbundle(wxString file = wxEmptyString);
     void        load_config(const DynamicPrintConfig& config);
-    void        select_tab(size_t tab);
+    // Select tab in m_tabpanel
+    // When tab == -1, will be selected last selected tab
+    void        select_tab(size_t tab = size_t(-1));
     void        select_view(const std::string& direction);
     // Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
     void        on_config_changed(DynamicPrintConfig* cfg) const ;
@@ -141,6 +167,7 @@ public:
 
     Plater*             m_plater { nullptr };
     wxNotebook*         m_tabpanel { nullptr };
+    SettingsDialog*     m_settings_dialog { nullptr };
     wxProgressDialog*   m_progress_dialog { nullptr };
     std::shared_ptr<ProgressStatusBar>  m_statusbar;
 
diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp
index 0905f4915..d9b9af016 100644
--- a/src/slic3r/GUI/ObjectDataViewModel.cpp
+++ b/src/slic3r/GUI/ObjectDataViewModel.cpp
@@ -1710,10 +1710,11 @@ bool BitmapChoiceRenderer::Render(wxRect rect, wxDC* dc, int state)
     {
         dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2);
         xoffset = icon.GetWidth() + 4;
+
+        if (rect.height==0)
+          rect.height= icon.GetHeight();
     }
 
-    if (rect.height==0)
-        rect.height= icon.GetHeight();
     RenderText(m_value.GetText(), xoffset, rect, dc, state);
 
     return true;
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 83eb6c76f..5b2b5703b 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -105,6 +105,7 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
 	if (!m_show_modified_btns) {
         field->m_Undo_btn->set_as_hidden();
 		field->m_Undo_to_sys_btn->set_as_hidden();
+		field->m_blinking_bmp->Hide();
 		return;
 	}
 
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index c4a43fbb0..0648c9f47 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -356,10 +356,10 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
         if (page_id == wxNOT_FOUND)
             return;
 
-        wxGetApp().tab_panel()->ChangeSelection(page_id);
+        wxGetApp().tab_panel()->SetSelection(page_id);
 
         // Switch to Settings NotePad
-        wxGetApp().mainframe->switch_to(false);
+        wxGetApp().mainframe->select_tab();
 
         /* In a case of a multi-material printing, for editing another Filament Preset
          * it's needed to select this preset for the "Filament settings" Tab
@@ -1101,9 +1101,8 @@ void Sidebar::jump_to_option(size_t selected)
     const Search::Option& opt = p->searcher.get_option(selected);
     wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category));
 
-    // Switch to the Settings NotePad, if plater is shown
-    if (p->plater->IsShown())
-        wxGetApp().mainframe->switch_to(false);
+    // Switch to the Settings NotePad
+    wxGetApp().mainframe->select_tab();
 }
 
 ObjectManipulation* Sidebar::obj_manipul()
@@ -1646,6 +1645,7 @@ struct Plater::priv
 
     void reset_all_gizmos();
     void update_ui_from_settings();
+    void update_main_toolbar_tooltips();
     std::shared_ptr<ProgressStatusBar> statusbar();
     std::string get_config(const std::string &key) const;
     BoundingBoxf bed_shape_bb() const;
@@ -2046,7 +2046,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
 
 
     // collapse sidebar according to saved value
-    sidebar->collapse(wxGetApp().app_config->get("collapsed_sidebar") == "1");
+    bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
+    sidebar->collapse(is_collapsed);
+    // Update an enable of the collapse_toolbar: if sidebar is collapsed, then collapse_toolbar should be visible
+    if (is_collapsed)
+        wxGetApp().app_config->set("show_collapse_button", "1");
 }
 
 Plater::priv::~priv()
@@ -2121,6 +2125,13 @@ void Plater::priv::update_ui_from_settings()
     preview->get_canvas3d()->update_ui_from_settings();
 }
 
+// Called after the print technology was changed.
+// Update the tooltips for "Switch to Settings" button in maintoolbar
+void Plater::priv::update_main_toolbar_tooltips()
+{
+    view3D->get_canvas3d()->update_tooltip_for_settings_item_in_main_toolbar();
+}
+
 std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar()
 {
     return main_frame->m_statusbar;
@@ -5286,6 +5297,10 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology)
 
     if (wxGetApp().mainframe)
         wxGetApp().mainframe->update_menubar();
+
+    p->update_main_toolbar_tooltips();
+
+    p->sidebar->get_searcher().set_printer_technology(printer_technology);
 }
 
 void Plater::changed_object(int obj_idx)
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index e2bccb1c7..88c643add 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -117,6 +117,13 @@ void PreferencesDialog::build()
 	m_optgroup_general->append_single_option_line(option);
 #endif
 
+	def.label = L("Show the button for the collapse sidebar");
+	def.type = coBool;
+	def.tooltip = L("If enabled, the button for the collapse sidebar will be appeared in top right corner of the 3D Scene");
+	def.set_default_value(new ConfigOptionBool{ app_config->get("show_collapse_button") == "1" });
+	option = Option(def, "show_collapse_button");
+	m_optgroup_general->append_single_option_line(option);
+
 	m_optgroup_camera = std::make_shared<ConfigOptionsGroup>(this, _(L("Camera")));
 	m_optgroup_camera->label_width = 40;
 	m_optgroup_camera->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
@@ -157,6 +164,8 @@ void PreferencesDialog::build()
 	create_icon_size_slider();
 	m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1");
 
+	create_settings_mode_widget();
+
 	auto sizer = new wxBoxSizer(wxVERTICAL);
 	sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
 	sizer->Add(m_optgroup_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
@@ -167,7 +176,7 @@ void PreferencesDialog::build()
 	auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
 	wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
 	btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); });
-	sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
+	sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5);
 
 	SetSizer(sizer);
 	sizer->SetSizeHints(this);
@@ -179,17 +188,46 @@ void PreferencesDialog::accept()
         warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME));
 	}
 
-	auto app_config = get_app_config();
-	for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) {
-		app_config->set(it->first, it->second);
+    auto app_config = get_app_config();
+
+	bool settings_layout_changed =	m_values.find("old_settings_layout_mode") != m_values.end() ||
+		                            m_values.find("new_settings_layout_mode") != m_values.end() ||
+		                            m_values.find("dlg_settings_layout_mode") != m_values.end();
+
+	if (settings_layout_changed) {
+		// the dialog needs to be destroyed before the call to recreate_gui()
+		// or sometimes the application crashes into wxDialogBase() destructor
+		// so we put it into an inner scope
+		wxMessageDialog dialog(nullptr,
+			            _L("Switching the settings layout mode will trigger application restart.\n"
+				                  "You will lose content of the plater.") + "\n\n" +
+			                   _L("Do you want to proceed?"),
+			wxString(SLIC3R_APP_NAME) + " - " + _L("Switching the settings layout mode"),
+			wxICON_QUESTION | wxOK | wxCANCEL);
+
+		if (dialog.ShowModal() == wxID_CANCEL)
+		{
+			int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 :
+				            app_config->get("new_settings_layout_mode") == "1" ? 1 :
+				            app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0;
+
+			m_layout_mode_box->SetSelection(selection);
+			return;
+		}
 	}
 
-	app_config->save();
+	for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
+		app_config->set(it->first, it->second);
 
+	app_config->save();
 	EndModal(wxID_OK);
 
-	// Nothify the UI to update itself from the ini file.
-    wxGetApp().update_ui_from_settings();
+	if (settings_layout_changed)
+		// recreate application, if settings layout was changed
+		wxGetApp().recreate_GUI();
+	else
+	    // Nothify the UI to update itself from the ini file.
+        wxGetApp().update_ui_from_settings();
 }
 
 void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect)
@@ -272,6 +310,38 @@ void PreferencesDialog::create_icon_size_slider()
 	m_optgroup_gui->sizer->Add(m_icon_size_sizer, 0, wxEXPAND | wxALL, em);
 }
 
+void PreferencesDialog::create_settings_mode_widget()
+{
+	wxString choices[] = {	_L("Old regular layout with tab bar"),
+							_L("New layout without the tab bar on the platter"),
+							_L("Settings will be shown in non-modal dialog")		};
+
+	auto app_config = get_app_config();
+	int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 :
+	                app_config->get("new_settings_layout_mode") == "1" ? 1 :
+	                app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0;
+
+	wxWindow* parent = m_optgroup_gui->ctrl_parent();
+
+	m_layout_mode_box = new wxRadioBox(parent, wxID_ANY, _L("Settings layout mode"), wxDefaultPosition, wxDefaultSize, WXSIZEOF(choices), choices,
+		3, wxRA_SPECIFY_ROWS);
+	m_layout_mode_box->SetFont(wxGetApp().normal_font());
+	m_layout_mode_box->SetSelection(selection);
+
+	m_layout_mode_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) {
+		int selection = e.GetSelection();
+
+		m_values["old_settings_layout_mode"] = boost::any_cast<bool>(selection == 0) ? "1" : "0";
+		m_values["new_settings_layout_mode"] = boost::any_cast<bool>(selection == 1) ? "1" : "0";
+		m_values["dlg_settings_layout_mode"] = boost::any_cast<bool>(selection == 2) ? "1" : "0";
+	});
+
+	auto sizer = new wxBoxSizer(wxHORIZONTAL);
+	sizer->Add(m_layout_mode_box, 1, wxALIGN_CENTER_VERTICAL);
+
+	m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND);
+}
+
 
 } // GUI
 } // Slic3r
\ No newline at end of file
diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp
index 35bf2b8c5..738e805b2 100644
--- a/src/slic3r/GUI/Preferences.hpp
+++ b/src/slic3r/GUI/Preferences.hpp
@@ -7,6 +7,8 @@
 #include <wx/dialog.h>
 #include <map>
 
+class wxRadioBox;
+
 namespace Slic3r {
 namespace GUI {
 
@@ -19,6 +21,7 @@ class PreferencesDialog : public DPIDialog
 	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_camera;
 	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_gui;
 	wxSizer*                            m_icon_size_sizer;
+	wxRadioBox*							m_layout_mode_box;
     bool                                isOSX {false};
 public:
 	PreferencesDialog(wxWindow* parent);
@@ -31,6 +34,7 @@ protected:
     void on_dpi_changed(const wxRect &suggested_rect) override;
     void layout();
     void create_icon_size_slider();
+    void create_settings_mode_widget();
 };
 
 } // GUI
diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp
index 844d2244c..33f097362 100644
--- a/src/slic3r/GUI/Search.cpp
+++ b/src/slic3r/GUI/Search.cpp
@@ -39,6 +39,23 @@ static const std::vector<std::wstring>& NameByType()
 	return data;
 }
 
+static char marker_by_type(Preset::Type type, PrinterTechnology pt)
+{
+    switch(type) {
+    case Preset::TYPE_PRINT:
+    case Preset::TYPE_SLA_PRINT:
+        return ImGui::PrintIconMarker;
+    case Preset::TYPE_FILAMENT:
+        return ImGui::FilamentIconMarker;
+    case Preset::TYPE_SLA_MATERIAL:
+        return ImGui::MaterialIconMarker;
+    case Preset::TYPE_PRINTER:
+        return pt == ptSLA ? ImGui::PrinterSlaIconMarker : ImGui::PrinterIconMarker;
+    default:
+        return ' ';
+	}
+}
+
 void FoundOption::get_marked_label_and_tooltip(const char** label_, const char** tooltip_) const
 {
     *label_   = marked_label.c_str();
@@ -106,17 +123,8 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
             emplace(opt_key, label);
         else
             for (int i = 0; i < cnt; ++i)
-                emplace(opt_key + "[" + std::to_string(i) + "]", label);
-
-        /*const GroupAndCategory& gc = groups_and_categories[opt_key];
-        if (gc.group.IsEmpty() || gc.category.IsEmpty())
-            continue;
-
-        if (!label.IsEmpty())
-            options.emplace_back(Option{opt_key, type,
-                                        label, _(label),
-                                        gc.group, _(gc.group),
-                                        gc.category, _(gc.category) });*/
+                // ! It's very important to use "#". opt_key#n is a real option key used in GroupAndCategory
+                emplace(opt_key + "#" + std::to_string(i), label); 
     }
 }
 
@@ -183,19 +191,19 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
 
     bool full_list = search.empty();
     std::wstring sep = L" : ";
-    const std::vector<std::wstring>& name_by_type = NameByType();
 
-    auto get_label = [this, &name_by_type, &sep](const Option& opt)
+    auto get_label = [this, &sep](const Option& opt)
     {
         std::wstring out;
+        out += marker_by_type(opt.type, printer_technology);
     	const std::wstring *prev = nullptr;
     	for (const std::wstring * const s : {
-	        view_params.type 		? &(name_by_type[opt.type]) : nullptr,
 	        view_params.category 	? &opt.category_local 		: nullptr,
 	        view_params.group 		? &opt.group_local			: nullptr,
 	        &opt.label_local })
     		if (s != nullptr && (prev == nullptr || *prev != *s)) {
-    			if (! out.empty())
+//    			if (! out.empty())
+      			if (out.size()>2)
     				out += sep;
     			out += *s;
     			prev = s;
@@ -203,17 +211,18 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
         return out;
     };
 
-    auto get_label_english = [this, &name_by_type, &sep](const Option& opt)
+    auto get_label_english = [this, &sep](const Option& opt)
     {
         std::wstring out;
+        out += marker_by_type(opt.type, printer_technology);
     	const std::wstring*prev = nullptr;
     	for (const std::wstring * const s : {
-	        view_params.type 		? &name_by_type[opt.type] 	: nullptr,
 	        view_params.category 	? &opt.category 			: nullptr,
 	        view_params.group 		? &opt.group				: nullptr,
 	        &opt.label })
     		if (s != nullptr && (prev == nullptr || *prev != *s)) {
-    			if (! out.empty())
+//    			if (! out.empty())
+      			if (out.size()>2)
     				out += sep;
     			out += *s;
     			prev = s;
@@ -221,9 +230,9 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
         return out;
     };
 
-    auto get_tooltip = [this, &name_by_type, &sep](const Option& opt)
+    auto get_tooltip = [this, &sep](const Option& opt)
     {
-        return  name_by_type[opt.type] + sep +
+        return  marker_by_type(opt.type, printer_technology) +
                 opt.category_local + sep +
                 opt.group_local + sep + opt.label_local;
     };
@@ -423,15 +432,15 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
 
     wxBoxSizer* check_sizer = new wxBoxSizer(wxHORIZONTAL);
 
-    check_type      = new wxCheckBox(this, wxID_ANY, _L("Type"));
     check_category  = new wxCheckBox(this, wxID_ANY, _L("Category"));
     check_group     = new wxCheckBox(this, wxID_ANY, _L("Group"));
+    check_english   = new wxCheckBox(this, wxID_ANY, _L("Search in English"));
 
     wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
 
-    check_sizer->Add(check_type,     0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
     check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
     check_sizer->Add(check_group,    0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
+    check_sizer->Add(check_english,  0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
     check_sizer->AddStretchSpacer(border);
     check_sizer->Add(cancel_btn,     0, wxALIGN_CENTER_VERTICAL);
 
@@ -450,7 +459,7 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
     search_list->Bind(wxEVT_LEFT_UP, &SearchDialog::OnMouseClick, this);
     search_list->Bind(wxEVT_KEY_DOWN,&SearchDialog::OnKeyDown, this);
 
-    check_type    ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
+    check_english ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
     check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
     check_group   ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
 
@@ -470,9 +479,9 @@ void SearchDialog::Popup(wxPoint position /*= wxDefaultPosition*/)
     update_list();
 
     const OptionViewParameters& params = searcher->view_params;
-    check_type->SetValue(params.type);
     check_category->SetValue(params.category);
     check_group->SetValue(params.group);
+    check_english->SetValue(params.english);
 
     this->SetPosition(position);
     this->ShowModal();
@@ -538,7 +547,7 @@ void SearchDialog::update_list()
 
     const std::vector<FoundOption>& filters = searcher->found_options();
     for (const FoundOption& item : filters)
-        search_list->Append(from_u8(item.label));
+        search_list->Append(from_u8(item.label).Remove(0, 1));
 }
 
 void SearchDialog::OnKeyDown(wxKeyEvent& event)
@@ -570,7 +579,7 @@ void SearchDialog::OnKeyDown(wxKeyEvent& event)
 void SearchDialog::OnCheck(wxCommandEvent& event)
 {
     OptionViewParameters& params = searcher->view_params;
-    params.type     = check_type->GetValue();
+    params.english  = check_english->GetValue();
     params.category = check_category->GetValue();
     params.group    = check_group->GetValue();
 
diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp
index 5fcb58f1e..60ef16c0f 100644
--- a/src/slic3r/GUI/Search.hpp
+++ b/src/slic3r/GUI/Search.hpp
@@ -66,9 +66,9 @@ struct FoundOption {
 
 struct OptionViewParameters
 {
-    bool type       {false};
     bool category   {false};
     bool group      {true };
+    bool english    {false};
 
     int  hovered_id {-1};
 };
@@ -77,6 +77,7 @@ class OptionsSearcher
 {
     std::string                             search_line;
     std::map<std::string, GroupAndCategory> groups_and_categories;
+    PrinterTechnology                       printer_technology;
 
     std::vector<Option>                     options {};
     std::vector<FoundOption>                found {};
@@ -120,6 +121,8 @@ public:
     const std::vector<FoundOption>& found_options() { return found; }
     const GroupAndCategory&         get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; }
     std::string& search_string() { return search_line; }
+
+    void set_printer_technology(PrinterTechnology pt) { printer_technology = pt; }
 };
 
 
@@ -167,9 +170,9 @@ class SearchDialog : public GUI::DPIDialog
 
     wxTextCtrl*     search_line    { nullptr };
     wxListBox*      search_list    { nullptr };
-    wxCheckBox*     check_type     { nullptr };
     wxCheckBox*     check_category { nullptr };
     wxCheckBox*     check_group    { nullptr };
+    wxCheckBox*     check_english  { nullptr };
 
     OptionsSearcher* searcher;