1 //------------------------------------------------------------------------------
2 // emNetwalkControlPanel.cpp
3 //
4 // Copyright (C) 2010-2011,2014-2015,2019 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #include <emNetwalk/emNetwalkControlPanel.h>
22 
23 
emNetwalkControlPanel(ParentArg parent,const emString & name,emView & contentView,emNetwalkModel * fileModel)24 emNetwalkControlPanel::emNetwalkControlPanel(
25 	ParentArg parent, const emString & name, emView & contentView,
26 	emNetwalkModel * fileModel
27 )
28 	: emLinearLayout(parent,name),
29 	ContentView(contentView)
30 {
31 	emPackGroup * mainGroup;
32 	emRasterLayout * l1, * l2, * l3;
33 
34 	Mdl=fileModel;
35 
36 	SetMinChildTallness(0.13);
37 	SetMaxChildTallness(2.0);
38 	SetAlignment(EM_ALIGN_TOP);
39 
40 	mainGroup=new emPackGroup(this,"","emNetwalk");
41 
42 	mainGroup->SetPrefChildTallness(0, 1.0);
43 	mainGroup->SetPrefChildTallness(1, 0.3);
44 	mainGroup->SetPrefChildTallness(2, 0.07);
45 	mainGroup->SetPrefChildTallness(3, 0.33);
46 	mainGroup->SetChildWeight(0, 0.3);
47 	mainGroup->SetChildWeight(1, 1.0);
48 	mainGroup->SetChildWeight(2, 0.105);
49 	mainGroup->SetChildWeight(3, 0.495);
50 
51 	GrAbout=new emLinearGroup(mainGroup,"about","About emNetwalk");
52 	LbAbout=new emLabel(GrAbout,"text",
53 		"emNetwalk is a clone of the addictive Netwalk puzzle game where pieces of a\n"
54 		"computer network have to be rotated in order to connect terminals to a server.\n"
55 		"In contrast to other implementations, emNetwalk has a very sophisticated random\n"
56 		"network generator which allows a more free and exact game configuration. In\n"
57 		"addition, emNetwalk provides a special option for making the game even more fun:\n"
58 		"The Dig Mode forbids to rotate pieces that are not yet near a server connection.\n"
59 		"\n"
60 		"How to play\n"
61 		"-----------\n"
62 		"\n"
63 		"In order to solve the puzzle, you have to connect all the terminals to the\n"
64 		"server. You can do this by rotating pieces of the network (cable segments,\n"
65 		"junctions, terminals, and the server). The solution must not contain any loops\n"
66 		"or islands, so that there is always exactly one path from the server to each\n"
67 		"terminal. Every game has exactly one such solution.\n"
68 		"\n"
69 		"Mouse functions:\n"
70 		"\n"
71 		"  Left button: Rotate piece counterclockwise.\n"
72 		"\n"
73 		"  Shift + left button: Rotate piece clockwise.\n"
74 		"\n"
75 		"  Right button: Mark or unmark a piece. A marked piece cannot be rotated.\n"
76 		"\n"
77 		"  Ctrl + left button + movement: Scroll board (only in borderless mode)\n"
78 		"\n"
79 		"Here are some tips for beginners:\n"
80 		"\n"
81 		"4-way junctions are always correct and must not be rotated.\n"
82 		"\n"
83 		"A straight segment besides a border must point along the border.\n"
84 		"\n"
85 		"One or more straight segments between two terminals must not connect the\n"
86 		"terminals.\n"
87 		"\n"
88 		"An arc segment between two straight segments requires that the straight\n"
89 		"segments have different orientations."
90 	);
91 	LbAbout->SetLabelAlignment(EM_ALIGN_TOP_LEFT);
92 
93 	GrStart=new emLinearGroup(mainGroup,"start","New Game");
94 	GrStart->SetOrientationThresholdTallness(0.16);
95 	GrStart->SetChildWeight(0,1.0);
96 	GrStart->SetChildWeight(1,0.6);
97 	l1=new emRasterLayout(GrStart,"l1");
98 	l1->SetPrefChildTallness(0.26);
99 	l2=new emRasterLayout(l1,"l2");
100 	l2->SetPrefChildTallness(0.15);
101 	l3=new emRasterLayout(l1,"l3");
102 	l3->SetPrefChildTallness(0.11);
103 	SfSize=new emScalarField(
104 		l2,"size","Size",
105 		"Here you can set the size of the board as the number\n"
106 		"of pieces in horizontal and vertical direction."
107 	);
108 	SfSize->SetMinMaxValues(5,25);
109 	SfSize->SetScaleMarkIntervals(5,1,0);
110 	SfSize->SetEditable();
111 	SfComplexity=new emScalarField(
112 		l2,"complexity","Complexity",
113 		"This is the difficulty of the network. The higher the value,\n"
114 		"the more junctions and terminals are generated per area."
115 	);
116 	SfComplexity->SetMinMaxValues(1,5);
117 	SfComplexity->SetScaleMarkIntervals(1,0);
118 	SfComplexity->SetEditable();
119 	CbBorderless=new emCheckBox(
120 		l3,"borderless","Borderless",
121 		"If this is enabled, connections can wrap from one edge to the\n"
122 		"opposite edge so that there are no borders. This makes the game\n"
123 		"more difficult. Remember that you can scroll the whole board\n"
124 		"with Ctrl + left mouse button + mouse movement."
125 	);
126 	CbBorderless->SetNoEOI();
127 	CbNoFourWayJunctions=new emCheckBox(
128 		l3,"no4wayjunctions","No 4-Way Junctions",
129 		"If this is enabled, the network will not contain any 4-way\n"
130 		"junctions. This makes the game more difficult."
131 	);
132 	CbNoFourWayJunctions->SetNoEOI();
133 	CbDigMode=new emCheckBox(
134 		l3,"digmode","Dig Mode",
135 		"If this is enabled, pieces that are not near a server connection\n"
136 		"are dug in and cannot be rotated, so that the puzzle has to be\n"
137 		"solved by \"digging\" from server to terminals. This makes the\n"
138 		"game more difficult."
139 	);
140 	CbDigMode->SetNoEOI();
141 	BtStart=new emButton(
142 		GrStart,"start","Start New Game",
143 		"Start a new game with the given settings.\n"
144 		"\n"
145 		"Hotkey: Ctrl+N"
146 	);
147 
148 	GrExtra=new emRasterGroup(mainGroup,"extra","Extra");
149 	GrExtra->SetPrefChildTallness(0.2);
150 	GrExtra->SetMinChildTallness(0.12);
151 	GrExtra->SetAlignment(EM_ALIGN_TOP_LEFT);
152 	GrExtra->SetBorderScaling(2.0);
153 	CbAutoMark=new emCheckBox(
154 		GrExtra,"automark","Auto Mark",
155 		"Whether to mark pieces automatically after rotating them."
156 	);
157 	CbAutoMark->SetNoEOI();
158 	BtUnmarkAll=new emButton(
159 		GrExtra,"unmarkall","Unmark All",
160 		"Unmark all pieces.\n"
161 		"\n"
162 		"Hotkey: Ctrl+U"
163 	);
164 	TfPenalty=new emTextField(
165 		mainGroup,"penalty","Penalty Points",
166 		"A penalty point is given whenever you rotate a piece once again\n"
167 		"after rotating at least one other piece in between. Advanced players\n"
168 		"should try to solve the puzzle without getting any penalty points."
169 	);
170 
171 	UpdateFields();
172 
173 	AddWakeUpSignal(Mdl->GetChangeSignal());
174 	AddWakeUpSignal(BtStart->GetClickSignal());
175 	AddWakeUpSignal(CbAutoMark->GetCheckSignal());
176 	AddWakeUpSignal(BtUnmarkAll->GetClickSignal());
177 }
178 
179 
~emNetwalkControlPanel()180 emNetwalkControlPanel::~emNetwalkControlPanel()
181 {
182 }
183 
184 
Cycle()185 bool emNetwalkControlPanel::Cycle()
186 {
187 	if (IsSignaled(Mdl->GetChangeSignal())) {
188 		UpdateFields();
189 	}
190 
191 	if (IsSignaled(BtStart->GetClickSignal())) {
192 		if (
193 			Mdl->GetFileState()==emFileModel::FS_LOADED ||
194 			Mdl->GetFileState()==emFileModel::FS_UNSAVED
195 		) {
196 			try {
197 				Mdl->TrySetup(
198 					(int)SfSize->GetValue(),
199 					(int)SfSize->GetValue(),
200 					CbBorderless->IsChecked(),
201 					CbNoFourWayJunctions->IsChecked(),
202 					(int)SfComplexity->GetValue(),
203 					CbDigMode->IsChecked(),
204 					CbAutoMark->IsChecked()
205 				);
206 			}
207 			catch (const emException & exception) {
208 				emDialog::ShowMessage(ContentView,"Error",exception.GetText());
209 			}
210 		}
211 	}
212 
213 	if (IsSignaled(CbAutoMark->GetCheckSignal())) {
214 		Mdl->SetAutoMark(CbAutoMark->IsChecked());
215 	}
216 
217 	if (IsSignaled(BtUnmarkAll->GetClickSignal())) {
218 		Mdl->UnmarkAll();
219 	}
220 
221 	return emLinearLayout::Cycle();
222 }
223 
224 
UpdateFields()225 void emNetwalkControlPanel::UpdateFields()
226 {
227 	SfSize->SetValue((Mdl->GetWidth()+Mdl->GetHeight()+1)/2);
228 	SfComplexity->SetValue(Mdl->GetComplexity());
229 	CbBorderless->SetChecked(Mdl->IsBorderless());
230 	CbNoFourWayJunctions->SetChecked(Mdl->IsNoFourWayJunctions());
231 	CbDigMode->SetChecked(Mdl->IsDigMode());
232 	CbAutoMark->SetChecked(Mdl->IsAutoMark());
233 	TfPenalty->SetText(emString::Format("%d",Mdl->GetPenaltyPoints()));
234 }
235