Kaynağa Gözat

属性弹框UI优化好了

张洋 1 ay önce
ebeveyn
işleme
f20c793868

+ 4 - 4
bin/Win32/Debug/zhipuzi_pos_windows/skin/diandan_nature_item.xml

@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Window>
 <Window>
-	<DiandanNatureItem padding="0,10,0,0">
-		<Label name="diandan_nature_layout_name" text="" font="diandan_nature_layout_name" height="30" />
+	<!-- 右 padding=15 补偿父容器右 inset=0,保证内容区仍有 15px 右间距;头与按钮区间距 12 -->
+	<DiandanNatureItem padding="0,10,15,0" childpadding="12">
+		<Label name="diandan_nature_layout_name" text="" font="113" textcolor="#FF2E9B5C" height="28" bkimage="file='grp_head.png' corner='4,4,4,4'" textpadding="13,0,0,0" />
 		
 		
 		<HorizontalLayout name="diandan_nature_layout_value">
 		<HorizontalLayout name="diandan_nature_layout_value">
-
 		</HorizontalLayout>
 		</HorizontalLayout>
 	</DiandanNatureItem>
 	</DiandanNatureItem>
-</Window>
+</Window>

+ 4 - 3
bin/Win32/Debug/zhipuzi_pos_windows/skin/diandan_nature_wnd.xml

@@ -6,13 +6,14 @@
 			<Button name="closebtn" padding="0,13,15,0" width="16" height="16" tooltip="关闭" normalimage="file='close_normal.png'" hotimage="file='close_hover.png'" pushedimage="file='close_normal.png'"/>
 			<Button name="closebtn" padding="0,13,15,0" width="16" height="16" tooltip="关闭" normalimage="file='close_normal.png'" hotimage="file='close_hover.png'" pushedimage="file='close_normal.png'"/>
 		</HorizontalLayout>
 		</HorizontalLayout>
 			
 			
-		<VerticalLayout inset="15,0,15,15" name="diandan_nature_layout" vscrollbar="true">
+		<!-- 右 inset=0 让滚动条贴到弹框最右侧;按钮区右间距下放给 DiandanNatureItem padding -->
+		<VerticalLayout inset="15,0,0,15" name="diandan_nature_layout" vscrollbar="true">
 			
 			
 		</VerticalLayout>
 		</VerticalLayout>
 		
 		
-		<HorizontalLayout height="56" valign="center" padding="0,30,0,20">
+		<HorizontalLayout height="44" valign="center" padding="0,18,0,18">
 			<Control />
 			<Control />
-			<Button name="diandan_nature_save" align="center" width="280" height="44" text="选好了" normalimage="file='btn_border_white.png' corner='5,5,5,5'" hotimage="file='btn_border_white_Hover.png' corner='5,5,5,5'" pushedimage="file='btn_border_white_Click.png' corner='5,5,5,5'" />
+			<Button name="diandan_nature_save" align="center" width="280" height="44" text="选好了" textcolor="#FFFFFFFF" font="114" normalimage="file='gd_btn_green_n.png' corner='8,8,8,8'" hotimage="file='gd_btn_green_h.png' corner='8,8,8,8'" pushedimage="file='gd_btn_green_p.png' corner='8,8,8,8'" />
 			<Control />
 			<Control />
 		</HorizontalLayout>
 		</HorizontalLayout>
 	</VerticalLayout>
 	</VerticalLayout>

BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/grp_head.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_h.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_n.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_p.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_sel_h.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_sel_n.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/nature_pill_sel_p.png


BIN
bin/Win32/Release/zhipuzi_pos_windows/zhipuzi_pos_windows.exe


+ 111 - 32
zhipuzi_pos_windows/control/CDiandanNatureItemUI.cpp

@@ -3,10 +3,40 @@
 
 
 #include "../wnd/CDiandanNatureWnd.h"
 #include "../wnd/CDiandanNatureWnd.h"
 
 
-CDiandanNatureItemUI::CDiandanNatureItemUI()
+namespace
 {
 {
+	// 测量指定字体下文本的像素宽度(GDI,用于 mini-html {x offset} 右对齐加价)
+	int MeasureTextWidth(DuiLib::CPaintManagerUI* pManager, int fontId, const std::wstring& text)
+	{
+		if (!pManager || text.empty()) return 0;
+
+		DuiLib::TFontInfo* pFontInfo = pManager->GetFontInfo(fontId);
+		if (!pFontInfo || !pFontInfo->hFont) return 0;
+
+		HDC hdc = GetDC(NULL);
+		if (!hdc) return 0;
+
+		HDC memDC = CreateCompatibleDC(hdc);
+		int width = 0;
+		if (memDC)
+		{
+			HGDIOBJ hOldFont = SelectObject(memDC, pFontInfo->hFont);
+			SIZE size = { 0, 0 };
+			if (GetTextExtentPoint32W(memDC, text.c_str(), (int)text.length(), &size))
+			{
+				width = size.cx;
+			}
+			SelectObject(memDC, hOldFont);
+			DeleteDC(memDC);
+		}
+		ReleaseDC(NULL, hdc);
+		return width;
+	}
 }
 }
 
 
+CDiandanNatureItemUI::CDiandanNatureItemUI()
+{
+}
 
 
 CDiandanNatureItemUI::~CDiandanNatureItemUI()
 CDiandanNatureItemUI::~CDiandanNatureItemUI()
 {
 {
@@ -35,39 +65,91 @@ void CDiandanNatureItemUI::addNatureValue(FoodNatureValue value)
 	m_nature_value.push_back(value);
 	m_nature_value.push_back(value);
 }
 }
 
 
+std::wstring CDiandanNatureItemUI::MakeBtnText(DuiLib::CPaintManagerUI* pManager, const std::wstring& name, int value, bool selected)
+{
+	std::wstring s = name;
+	if (value > 0)
+	{
+		// 文本区宽度 = 按钮 185 - 左 padding 12 - 右 padding 12 - 右侧安全边距 2
+		const int TEXT_AREA_W = 185 - 12 - 12 - 2;
+		int nameFontId = selected ? 112 : 12;
+		int nameW = MeasureTextWidth(pManager, nameFontId, name);
+
+		std::wstring price = L"+" + std::to_wstring(value);
+		int priceW = MeasureTextWidth(pManager, 11, price);
+
+		int offset = TEXT_AREA_W - nameW - priceW;
+		if (offset < 4) offset = 4; // 最小间距,防止名字过长时重叠
+
+		// 加价橙色右对齐;选中态仍保持橙色,与绿色名称形成 C3 分色效果
+		s += L"{x " + std::to_wstring(offset) + L"}<c #C47410><f 11>" + price + L"</f></c>";
+	}
+	return s;
+}
+
+void CDiandanNatureItemUI::ApplySelectStyle(CButtonUI* pBtn, int index, bool selected)
+{
+	DuiLib::CPaintManagerUI* pManager = pBtn->GetManager();
+
+	if (selected)
+	{
+		// C3 选中态:白底 + 主绿描边 + 绿字
+		pBtn->SetNormalImage(L"file='nature_pill_sel_n.png'");
+		pBtn->SetHotImage(L"file='nature_pill_sel_h.png'");
+		pBtn->SetPushedImage(L"file='nature_pill_sel_p.png'");
+		pBtn->SetTextColor(0xFF60B177);
+		pBtn->SetHotTextColor(0xFF60B177);
+		pBtn->SetPushedTextColor(0xFF60B177);
+		pBtn->SetFont(112);
+	}
+	else
+	{
+		// C3 未选中态:白底 + 浅灰描边 + 深色字
+		pBtn->SetNormalImage(L"file='nature_pill_n.png'");
+		pBtn->SetHotImage(L"file='nature_pill_h.png'");
+		pBtn->SetPushedImage(L"file='nature_pill_p.png'");
+		pBtn->SetTextColor(0xFF1F2329);
+		pBtn->SetHotTextColor(0xFF1F2329);
+		pBtn->SetPushedTextColor(0xFF1F2329);
+		pBtn->SetFont(12);
+	}
+
+	FoodNatureValue& v = m_nature_value[index];
+	pBtn->SetText(MakeBtnText(pManager, CLewaimaiString::UTF8ToUnicode(v.name), v.value, selected).c_str());
+	pBtn->Invalidate();
+}
+
 void CDiandanNatureItemUI::ShowNatureValue()
 void CDiandanNatureItemUI::ShowNatureValue()
 {
 {
 	CHorizontalLayoutUI* pValueLayout = static_cast<CHorizontalLayoutUI*>(this->FindSubControl(_T("diandan_nature_layout_value")));
 	CHorizontalLayoutUI* pValueLayout = static_cast<CHorizontalLayoutUI*>(this->FindSubControl(_T("diandan_nature_layout_value")));
 
 
 	int totoal_value_size = m_nature_value.size();
 	int totoal_value_size = m_nature_value.size();
 
 
-	int nRows = (totoal_value_size - 1) / 5 + 1;
-	int nCols = 5;
+	int nRows = (totoal_value_size - 1) / 4 + 1;
+	int nCols = 4;
 
 
 	//设置属性区域的高度
 	//设置属性区域的高度
 	pValueLayout->SetFixedHeight(nRows * 54);
 	pValueLayout->SetFixedHeight(nRows * 54);
 
 
-	this->SetFixedHeight(nRows * 54 + 30);
+	// 组高 = 网格高 + 分组头 28 + 头与网格间距 12(childpadding) + 顶 padding 10
+	// 注意:XML 中 padding top=10 会减少内容区高度,必须同步补回来,否则最后一行底部被截断
+	this->SetFixedHeight(nRows * 54 + 28 + 12 + 10);
 
 
 	//开始设置每个控件的位置
 	//开始设置每个控件的位置
 	int value_num = 0;
 	int value_num = 0;
 	for (std::vector<FoodNatureValue>::iterator it = m_nature_value.begin(); it != m_nature_value.end(); it++)
 	for (std::vector<FoodNatureValue>::iterator it = m_nature_value.begin(); it != m_nature_value.end(); it++)
 	{
 	{
 		//这里面的是属性值信息
 		//这里面的是属性值信息
-		FoodNatureValue curNature = *it;
-
-		std::string valuename = curNature.name;
-		int valueprice = curNature.value;
-
 		CButtonUI* newButton = new CButtonUI();
 		CButtonUI* newButton = new CButtonUI();
 
 
-		newButton->SetFixedWidth(145);
+		newButton->SetFixedWidth(185);
 		newButton->SetFixedHeight(44);
 		newButton->SetFixedHeight(44);
-		newButton->SetText(CLewaimaiString::UTF8ToUnicode(valuename).c_str());
-
-		newButton->SetBorderSize(1);
-		newButton->SetBorderColor(0xFFA9A9A9);
-		newButton->SetTextColor(0xFFA9A9A9);
+		newButton->SetShowHtml(true);
+		newButton->SetTextPadding(RECT{ 12, 0, 12, 0 });
+		newButton->SetBorderSize(0);
+		newButton->SetBkColor(0);
+		newButton->SetHotBkColor(0);
+		newButton->SetPushedBkColor(0);
 
 
 		//设置定义属性,在点击按钮的时候好区分
 		//设置定义属性,在点击按钮的时候好区分
 		newButton->SetAttribute(L"name", L"diandan_nature_value_btn");
 		newButton->SetAttribute(L"name", L"diandan_nature_value_btn");
@@ -77,13 +159,13 @@ void CDiandanNatureItemUI::ShowNatureValue()
 		//必须先Add,才能调用下面的SetPos,否则无效
 		//必须先Add,才能调用下面的SetPos,否则无效
 		pValueLayout->Add(newButton);
 		pValueLayout->Add(newButton);
 
 
-		//设置位置,根据行数和列数来计算,行数和列数第一个都是1,按钮宽度145,高度44,右和下间距10
-		int curRow = value_num / 5 + 1;
-		int curCol = value_num % 5 + 1;
+		//设置位置,根据行数和列数来计算,行数和列数第一个都是1,按钮宽度185,高度44,右和下间距10
+		int curRow = value_num / 4 + 1;
+		int curCol = value_num % 4 + 1;
 
 
 		RECT rect;
 		RECT rect;
-		rect.left = (curCol - 1) * 155;
-		rect.right = rect.left + 145;
+		rect.left = (curCol - 1) * 195;
+		rect.right = rect.left + 185;
 		rect.top = (curRow - 1) * 54;
 		rect.top = (curRow - 1) * 54;
 		rect.bottom = rect.top + 44;
 		rect.bottom = rect.top + 44;
 
 
@@ -98,6 +180,9 @@ void CDiandanNatureItemUI::ShowNatureValue()
 		newButton->SetFixedWidth(rect.right - rect.left);
 		newButton->SetFixedWidth(rect.right - rect.left);
 		newButton->SetFixedHeight(rect.bottom - rect.top);
 		newButton->SetFixedHeight(rect.bottom - rect.top);
 
 
+		//默认未选中样式(C3 白底描边 + 右对齐加价)
+		ApplySelectStyle(newButton, value_num, false);
+
 		value_num++;
 		value_num++;
 	}
 	}
 
 
@@ -109,8 +194,7 @@ void CDiandanNatureItemUI::ShowNatureValue()
 		m_nature_value[0].is_select = true;
 		m_nature_value[0].is_select = true;
 
 
 		CButtonUI* newButton = static_cast<CButtonUI*>(pValueLayout->GetItemAt(0));
 		CButtonUI* newButton = static_cast<CButtonUI*>(pValueLayout->GetItemAt(0));
-		newButton->SetBorderColor(0xFFFF4500);
-		newButton->SetTextColor(0xFFFF4500);
+		ApplySelectStyle(newButton, 0, true);
 
 
 		m_nSelectNum = 1;
 		m_nSelectNum = 1;
 	}
 	}
@@ -126,8 +210,7 @@ void CDiandanNatureItemUI::ShowNatureValue()
 			m_nature_value[index].is_select = true;
 			m_nature_value[index].is_select = true;
 
 
 			CButtonUI* newButton = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
 			CButtonUI* newButton = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
-			newButton->SetBorderColor(0xFFFF4500);
-			newButton->SetTextColor(0xFFFF4500);
+			ApplySelectStyle(newButton, index, true);
 
 
 			m_nSelectNum++;
 			m_nSelectNum++;
 		}
 		}
@@ -158,8 +241,7 @@ void CDiandanNatureItemUI::SetNatureSelected(int index)
 			m_nature_value[index].is_select = false;
 			m_nature_value[index].is_select = false;
 
 
 			CButtonUI* old_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
 			CButtonUI* old_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
-			old_btn->SetBorderColor(0xFFA9A9A9);
-			old_btn->SetTextColor(0xFFA9A9A9);
+			ApplySelectStyle(old_btn, index, false);
 
 
 			m_nSelectNum--;
 			m_nSelectNum--;
 		}
 		}
@@ -179,8 +261,7 @@ void CDiandanNatureItemUI::SetNatureSelected(int index)
 					m_nature_value[num].is_select = false;
 					m_nature_value[num].is_select = false;
 
 
 					CButtonUI* old_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(num));
 					CButtonUI* old_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(num));
-					old_btn->SetBorderColor(0xFFA9A9A9);
-					old_btn->SetTextColor(0xFFA9A9A9);
+					ApplySelectStyle(old_btn, num, false);
 				}
 				}
 
 
 				num++;
 				num++;
@@ -190,8 +271,7 @@ void CDiandanNatureItemUI::SetNatureSelected(int index)
 			m_nature_value[index].is_select = true;
 			m_nature_value[index].is_select = true;
 
 
 			CButtonUI* new_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
 			CButtonUI* new_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
-			new_btn->SetBorderColor(0xFFFF4500);
-			new_btn->SetTextColor(0xFFFF4500);
+			ApplySelectStyle(new_btn, index, true);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -206,8 +286,7 @@ void CDiandanNatureItemUI::SetNatureSelected(int index)
 			m_nature_value[index].is_select = true;
 			m_nature_value[index].is_select = true;
 
 
 			CButtonUI* new_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
 			CButtonUI* new_btn = static_cast<CButtonUI*>(pValueLayout->GetItemAt(index));
-			new_btn->SetBorderColor(0xFFFF4500);
-			new_btn->SetTextColor(0xFFFF4500);
+			ApplySelectStyle(new_btn, index, true);
 
 
 			m_nSelectNum++;
 			m_nSelectNum++;
 		}
 		}

+ 5 - 0
zhipuzi_pos_windows/control/CDiandanNatureItemUI.h

@@ -3,6 +3,7 @@
 #include <string>
 #include <string>
 
 
 class CDiandanNatureWnd;
 class CDiandanNatureWnd;
+namespace DuiLib { class CButtonUI; class CPaintManagerUI; }
 
 
 //这个对应的是一个属性值
 //这个对应的是一个属性值
 class FoodNatureValue
 class FoodNatureValue
@@ -135,5 +136,9 @@ private:
 	//如果是修改规格,这里表示当前属性默认选中的N个属性值
 	//如果是修改规格,这里表示当前属性默认选中的N个属性值
 	FoodNatureSelectValue m_InitFoodNatureSelectValue;
 	FoodNatureSelectValue m_InitFoodNatureSelectValue;
 
 
+	//辅助:根据选中态生成按钮文案(名称 + 加价双色,加价右对齐)并切换三态药丸图
+	std::wstring MakeBtnText(DuiLib::CPaintManagerUI* pManager, const std::wstring& name, int value, bool selected);
+	void ApplySelectStyle(DuiLib::CButtonUI* pBtn, int index, bool selected);
+
 	//int m_nSelectIndex = 0;
 	//int m_nSelectIndex = 0;
 };
 };

BIN
zhipuzi_pos_windows/resource/skin.zip