nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "TreeControl.h" 00025 00026 namespace nux 00027 { 00028 00029 TreeItem::TreeItem (const TCHAR *name, NodeParameterType type) 00030 : TableItem (name, type) 00031 { 00032 Close(); 00033 } 00034 00035 TreeItem::~TreeItem() 00036 { 00037 00038 } 00039 00040 long TreeItem::ProcessPropertyEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00041 { 00042 long ret = TraverseInfo; 00043 00044 return ret; 00045 } 00046 00047 void TreeItem::DrawProperty (GraphicsEngine &GfxContext, TableCtrl *table, bool force_draw, Geometry geo, const BasePainter &Painter, 00048 RowHeader *row, const std::vector<ColumnHeader>& column_vector, Color ItemBackgroundColor) 00049 { 00050 Geometry FirstColumnGeometry = m_ItemGeometryVector[0]; 00051 00052 if (isDirtyItem() ) 00053 { 00054 t_u32 nBackground; 00055 00056 if (m_bIsMouseInside) 00057 { 00058 nBackground = table->PushItemBackground (GfxContext, this, true); 00059 } 00060 else 00061 { 00062 nBackground = table->PushItemBackground (GfxContext, this, false); 00063 } 00064 00065 Painter.PaintTextLineStatic (GfxContext, GetSysFont(), geo, row->_table_item->GetName(), GetItemTextColor()); 00066 table->PopItemBackground (GfxContext, nBackground); 00067 } 00068 } 00069 00070 void TreeItem::ComputePropertyLayout (int x, int y, RowHeader *row, const std::vector<ColumnHeader>& column_vector) 00071 { 00072 00073 } 00074 00075 int TreeItem::GetItemBestHeight() 00076 { 00077 return ITEMDEFAULTHEIGHT; 00078 } 00079 00081 TreeControl::TreeControl() 00082 : TableCtrl (false) 00083 { 00084 TableCtrl::ShowColumnHeader (true); 00085 TableCtrl::ShowRowHeader (false); 00086 TableCtrl::EnableColumnResizing (true); 00087 TableCtrl::EnableApplyItemBestHeight (false); 00088 } 00089 00090 TreeControl::~TreeControl() 00091 { 00092 00093 } 00094 00095 void TreeControl::OnMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00096 { 00097 int previous_click_row = m_selectedRow; 00098 00099 m_selectedTableItem = 0; 00100 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 00101 00102 m_selectedGeometry.SetX (0); 00103 m_selectedGeometry.SetY (0); 00104 m_selectedGeometry.SetWidth (0); 00105 m_selectedGeometry.SetHeight (0); 00106 00107 if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 00108 { 00109 // selected item geometry 00110 int sx, sy, sw, sh; 00111 sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX(); 00112 sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(); 00113 sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(); 00114 sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight(); 00115 00116 m_selectedGeometry = Geometry (sx, sy, sw, sh); 00117 // sigItemSelected.emit(m_selectedRow, m_selectedColumn); 00118 // sigTableItemSelected.emit(*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn); 00119 } 00120 00121 if (1) 00122 { 00123 // This is a double click 00124 if ( (m_selectedRow == -1) || (m_selectedColumn == -1) ) 00125 return; 00126 00127 00128 if (!m_row_header[m_selectedRow]->_table_item->isOpen() && (m_row_header[m_selectedRow]->_table_item->FirstChildNode() || m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton() ) ) 00129 { 00130 // If it is not open, then open it. 00131 OpOpenItem (m_row_header[m_selectedRow]->_table_item); 00132 //if(m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 00133 } 00134 else 00135 { 00136 if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() /*|| m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton()*/) 00137 { 00138 Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0]; 00139 geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth); 00140 geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() ); 00141 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 00142 00143 if (geo.IsPointInside (x, y) ) 00144 { 00145 if (m_row_header[m_selectedRow]->_table_item->isOpen() ) 00146 { 00147 OpCloseItem (m_row_header[m_selectedRow]->_table_item); 00148 00149 if (IsSizeMatchContent() ) 00150 { 00151 // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content. 00152 // We need to call a PaintBackground on the area of the Table (area before the item is closed). 00153 m_DrawBackgroundOnPreviousGeometry = true; 00154 m_PreviousGeometry = GetGeometry(); 00155 // Initiate layout re computation from the top. This should be done with InitiateResizeLayout(); 00156 // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry()); 00157 SetGeometry (GetGeometry() ); 00158 } 00159 } 00160 else 00161 { 00162 OpOpenItem (m_row_header[m_selectedRow]->_table_item); 00163 } 00164 } 00165 else 00166 { 00167 //do nothing 00168 // You have to click on the Open/Close button to close the item 00169 } 00170 } 00171 } 00172 00173 FormatTable(); 00174 ComputeChildLayout(); 00175 } 00176 00177 if ( (previous_click_row >= 0) && (previous_click_row != m_selectedRow) && (m_row_header[previous_click_row]->_table_item->FirstChildNode() == 0) ) 00178 OpCloseItem (m_row_header[previous_click_row]->_table_item); 00179 00180 //else if((previous_click_row >= 0) && (m_row_header[previous_click_row]->_table_item->FirstChildNode() == 0)) 00181 // OpCloseItem(m_row_header[previous_click_row]->_table_item); 00182 00183 00184 { 00185 sigItemSelected.emit (m_selectedRow, m_selectedColumn); 00186 sigTableItemSelected.emit (*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn); 00187 } 00188 QueueDraw(); 00189 } 00190 00191 void TreeControl::mouse_double_click (int x, int y, unsigned long button_flags, unsigned long key_flags) 00192 { 00193 if ( (m_selectedRow == -1) || (m_selectedColumn == -1) ) 00194 { 00195 // The double click becomes a simple click if we know in advance that the first click didn't select anything. 00196 //OnMouseDown(x, y, button_flags, key_flags); 00197 return; 00198 } 00199 00200 int previous_click_row = m_selectedRow; 00201 00202 m_selectedTableItem = 0; 00203 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 00204 00205 if ( (m_selectedTableItem == 0) || (m_selectedRow == -1) || (m_selectedColumn == -1) ) 00206 return; 00207 00208 if (m_selectedRow != previous_click_row) 00209 { 00210 // The second button down of this double click is not on the same row. Interpret this as a mouse down. 00211 OnMouseDown (x, y, button_flags, key_flags); 00212 return; 00213 } 00214 00215 m_selectedGeometry.SetX (0); 00216 m_selectedGeometry.SetY (0); 00217 m_selectedGeometry.SetWidth (0); 00218 m_selectedGeometry.SetHeight (0); 00219 00220 if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 00221 { 00222 // selected item geometry 00223 int sx, sy, sw, sh; 00224 sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX(); 00225 sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(); 00226 sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(); 00227 sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight(); 00228 00229 m_selectedGeometry = Geometry (sx, sy, sw, sh); 00230 // we could send a signal meaning a double click has happened on an item. 00231 //sigItemDoubleClick.emit(m_row_header[m_selectedRow]->_table_item); 00232 } 00233 00234 // Check if item as a child node. If not, there is no point in opening/closing it. 00235 if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() /*|| m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton()*/) 00236 { 00237 Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0]; 00238 geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth); 00239 geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() ); 00240 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 00241 00242 if (geo.IsPointInside (x, y) ) 00243 { 00244 OnMouseDown (x, y, button_flags, key_flags); 00245 } 00246 else 00247 { 00248 // if(m_row_header[m_selectedRow]->_table_item->isOpen()) 00249 // { 00250 // OpCloseItem(m_row_header[m_selectedRow]->_table_item); 00251 // if(IsSizeMatchContent()) 00252 // { 00253 // // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content. 00254 // // We need to call a PaintBackground on the area of the Table (area before the item is closed). 00255 // m_DrawBackgroundOnPreviousGeometry = true; 00256 // m_PreviousGeometry = GetGeometry(); 00257 // // Initiate layout re computation from the top. This should be done with InitiateResizeLayout(); 00258 // // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry()); 00259 // SetGeometry(GetGeometry()); 00260 // } 00261 // } 00262 // else 00263 // { 00264 // OpOpenItem(m_row_header[m_selectedRow]->_table_item); 00265 // } 00266 } 00267 } 00268 00269 FormatTable(); 00270 ComputeChildLayout(); 00271 } 00272 00273 00274 }