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