xref: /haiku/src/libs/alm/Column.cpp (revision 8a990d5228b2d1099e3062180532ba709dfeef6d)
1 /*
2  * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
3  * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
4  * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
5  * Distributed under the terms of the MIT License.
6  */
7 
8 
9 #include "Column.h"
10 
11 #include "ALMLayout.h"
12 #include "Tab.h"
13 
14 
15 using namespace LinearProgramming;
16 
17 
18 /**
19  * The left boundary of the column.
20  */
21 XTab*
22 Column::Left() const
23 {
24 	return fLeft;
25 }
26 
27 
28 /**
29  * The right boundary of the column.
30  */
31 XTab*
32 Column::Right() const
33 {
34 	return fRight;
35 }
36 
37 
38 /**
39  * Gets the column directly to the left of this column.
40  */
41 Column*
42 Column::Previous() const
43 {
44 	return fPrevious;
45 }
46 
47 
48 /**
49  * Sets the column directly to the left of this column.
50  * May be null.
51  */
52 void
53 Column::SetPrevious(Column* value)
54 {
55 	// if there should be no column directly left of this column, then we have to
56 	// separate any such column and can remove any constraint that was used
57 	// to glue this column to it
58 	if (value == NULL) {
59 		if (fPrevious == NULL) return;
60 		fPrevious->fNext = NULL;
61 		fPrevious->fNextGlue = NULL;
62 		fPrevious = NULL;
63 		delete fPreviousGlue;
64 		fPreviousGlue = NULL;
65 		return;
66 	}
67 
68 	// otherwise we have to set up the pointers and the glue constraint accordingly
69 	if (value->fNext != NULL)
70 		value->SetNext(NULL);
71 	if (fPrevious != NULL)
72 		SetPrevious(NULL);
73 
74 	fPrevious = value;
75 	fPrevious->fNext = this;
76 	value->fNextGlue = value->Right()->IsEqual(Left());
77 	fPreviousGlue = value->fNextGlue;
78 }
79 
80 
81 /**
82  * Gets the column directly to the right of this column.
83  */
84 Column*
85 Column::Next() const
86 {
87 	return fNext;
88 }
89 
90 
91 /**
92  * Sets the column directly to the right of this column.
93  * May be null.
94  */
95 void
96 Column::SetNext(Column* value)
97 {
98 	// if there should be no column directly right of this column, then we have to
99 	// separate any such column and can remove any constraint that was used
100 	// to glue this column to it
101 	if (value == NULL) {
102 		if (fNext == NULL) return;
103 		fNext->fPrevious = NULL;
104 		fNext->fPreviousGlue = NULL;
105 		fNext = NULL;
106 		delete fNextGlue;
107 		fNextGlue = NULL;
108 		return;
109 	}
110 
111 	// otherwise we have to set up the pointers and the glue constraint accordingly
112 	if (value->fPrevious != NULL)
113 		value->SetPrevious(NULL);
114 	if (fNext != NULL)
115 		SetNext(NULL);
116 
117 	fNext = value;
118 	fNext->fPrevious = this;
119 	value->fPreviousGlue = Right()->IsEqual(value->Left());
120 	fNextGlue = value->fPreviousGlue;
121 }
122 
123 
124 /**
125  * Inserts the given column directly to the left of this column.
126  *
127  * @param column	the column to insert
128  */
129 void
130 Column::InsertBefore(Column* column)
131 {
132 	SetPrevious(column->fPrevious);
133 	SetNext(column);
134 }
135 
136 
137 /**
138  * Inserts the given column directly to the right of this column.
139  *
140  * @param column	the column to insert
141  */
142 void
143 Column::InsertAfter(Column* column)
144 {
145 	SetNext(column->fNext);
146 	SetPrevious(column);
147 }
148 
149 
150 /**
151  * Constrains this column to have the same width as the given column.
152  *
153  * @param column	the column that should have the same width
154  * @return the resulting same-width constraint
155  */
156 Constraint*
157 Column::HasSameWidthAs(Column* column)
158 {
159 	Constraint* constraint = fLS->AddConstraint(
160 		-1.0, Left(), 1.0, Right(), 1.0, column->Left(), -1.0, column->Right(),
161 		kEQ, 0.0);
162 	fConstraints.AddItem(constraint);
163 	return constraint;
164 }
165 
166 
167 ConstraintList*
168 Column::Constraints() const
169 {
170 	return const_cast<ConstraintList*>(&fConstraints);
171 }
172 
173 
174 /**
175  * Destructor.
176  * Removes the column from the specification.
177  */
178 Column::~Column()
179 {
180 	if (fPrevious != NULL)
181 		fPrevious->SetNext(fNext);
182 	for (int32 i = 0; i < fConstraints.CountItems(); i++)
183 		delete fConstraints.ItemAt(i);
184 	delete fLeft;
185 	delete fRight;
186 }
187 
188 
189 /**
190  * Constructor.
191  */
192 Column::Column(BALMLayout* layout)
193 {
194 	fLS = layout->Solver();
195 	fLeft = layout->AddXTab();
196 	fRight = layout->AddXTab();
197 }
198 
199