Compare commits

...

452 Commits

Author SHA1 Message Date
9d5cc43d71 Merge pull request 'Development' (#543) from Development into master
Merging dev into master after successful testing.
2025-05-01 11:25:49 -04:00
06159c6b68 Merge pull request 'F2025-011 Format changes are needed to account for ABN procedures.' (#542) from F2025-011 into Development
good for testing phase
2025-04-30 09:55:55 -04:00
22c14d169b F2025-011 Format changes are needed to account for ABN procedures.
Adjustments to PSI location and Abnormal Procedure Steps Sections
2025-04-30 09:50:09 -04:00
db09db3cd0 Merge pull request 'F2025-011 Format changes are needed to account for ABN procedures.' (#541) from F2025-011 into Development
ready for testing phase
2025-04-28 13:33:44 -04:00
ba8a8b8673 F2025-011 Format changes are needed to account for ABN procedures. 2025-04-28 12:08:10 -04:00
bc1370ab29 Merge pull request 'Development' (#540) from Development into master
Merging changes from Development into master after successful testing.
2025-04-23 15:13:56 -04:00
6f354bfeee Merge pull request 'B2025-010 - Adjusted the positioning of the procedure title in the Catawba Deviation Format so that it is centered' (#539) from B2025-010 into Development
Format only change.  Ready for testing
2025-04-11 09:14:38 -04:00
818d764b3d B2025-010 - Adjusted the positioning of the procedure title in the Catawba Deviation Format so that it is centered 2025-04-11 09:11:02 -04:00
689ea71846 Merge pull request 'B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search-2' (#538) from B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search-2 into Development
good for testing phase
2025-04-07 14:05:24 -04:00
66295594e9 B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search-2 2025-04-07 13:46:28 -04:00
042b80b9f4 Merge pull request 'B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search' (#537) from B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search into Development
Good for testing phase
2025-04-07 10:59:46 -04:00
c4da241516 B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search 2025-04-07 10:48:40 -04:00
74ccbfa760 B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search 2025-04-04 13:13:28 -04:00
46d8838d0e B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search 2025-04-04 10:48:48 -04:00
94d2c32025 Merge pull request 'Added the format file used for the pre-tend ACME data which is used when updating the PROMS User Manual' (#536) from ACME_formats into Development
format used internally when working on the PROMS User Manual
2025-04-04 10:40:40 -04:00
64124cc0f7 Added the format file used for the pre-tend ACME data which is used when updating the PROMS User Manual 2025-04-04 10:38:26 -04:00
24c5bc5097 B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search 2025-04-03 18:01:13 -04:00
1ffde5de50 B2022-031-Add-filtering-for-Proc-and-Section-name-from-Global-Search 2025-04-03 14:20:21 -04:00
eaf2b14cfc Merge pull request 'Development' (#535) from Development into master
Merging all changes from development into master after successful testing.
2025-03-26 09:25:11 -04:00
3828da2f8f Merge pull request 'C2024-041-Disable-UCF-(User-Control-of-Format)-options-3' (#534) from C2024-041-Disable-UCF-(User-Control-of-Format)-options-3 into Development
good for testing phase
2025-03-24 08:15:21 -04:00
1554d3cc33 C2024-041-Disable-UCF-(User-Control-of-Format)-options-3 2025-03-23 19:35:06 -04:00
d808b306b6 Merge pull request 'C2024-041-Disable-UCF-(User-Control-of-Format)-options-2' (#533) from C2024-041-Disable-UCF-(User-Control-of-Format)-options-2 into Development
good for testing phase
2025-03-21 08:18:08 -04:00
45aeb808fa C2024-041-Disable-UCF-(User-Control-of-Format)-options-2 2025-03-20 17:06:28 -04:00
74f9fc0c18 Merge pull request 'F2025-004 Customer requested the addition of a Two Column Attachment section type' (#531) from F2025-004_Ginna into Development
Format only change.  Good for testing phase
2025-03-06 16:15:32 -05:00
c2c90a2c2e F2025-004 Customer requested the addition of a Two Column Attachment section type 2025-03-06 16:13:52 -05:00
1cf7d81aa5 Merge pull request 'Development' (#530) from Development into master
Merging all changes through B2025-017 from dev into master after successful testing.
2025-03-04 10:24:28 -05:00
05ab077dda Merge pull request 'B2025-017-Print-Section-Sub-Section-v2' (#529) from B2025-017-Print-Section-Sub-Section-v2 into Development
good for testing phase
2025-02-28 08:16:52 -05:00
1ae422c74e B2025-017-Print-Section-Sub-Section-v2 2025-02-27 19:16:47 -05:00
5da62c3a5d Merge pull request 'Updated the developer tool that copied the format files to the FMTall an GENMACall folders. Added a list box to show what format files will not be copied.' (#528) from DeveloperToolUpdate into Development
This is an update to a tool that the developers use and is not released to the customers.
No testing required,
2025-02-27 11:21:53 -05:00
86a98118fb Updated the developer tool that copied the format files to the FMTall an GENMACall folders. Added a list box to show what format files will not be copied. 2025-02-27 11:20:31 -05:00
6a51208a13 Merge pull request 'B2025-020 Fixed NULL reference error while running the Refresh Transitions administrator tool.' (#527) from B2025-020_UpdateTransitions into Development
Looks good.
Ready for QA.
2025-02-26 11:48:06 -05:00
0749f5e724 B2025-020 Fixed NULL reference error while running the Refresh Transitions administrator tool. 2025-02-26 11:07:17 -05:00
f65644f553 Merge pull request 'B2025-018 PROMS - Issues with folder order in tree view.' (#526) from B2025-018 into Development
good for testing phase
2025-02-21 16:05:19 -05:00
dc74da6e86 B2025-018 PROMS - Issues with folder order in tree view. 2025-02-21 15:52:16 -05:00
301c4c2c97 Merge pull request 'C2025-019 RO Editor - Update the Orphaned RO Record text file to save in the current RO folder instead of the users appdata folder.' (#525) from C2025-019 into Development
Good for testing phase.
2025-02-20 16:04:06 -05:00
8ec820a7f7 C2025-019 RO Editor - Update the Orphaned RO Record text file to save in the current RO folder instead of the users appdata folder.
Found while using the WEP ROMOD database and the ROEPU folder.
Note for Word doc:  Update D.2.10 in the PROMS Manual for this update
2025-02-20 15:54:29 -05:00
f11a9536f0 Merge pull request 'Development' (#524) from Development into master
Merging all changes through B2025-015 from development into master after successful testing.
2025-02-20 15:33:44 -05:00
18734e0f85 Merge pull request 'B2025-015 RO Editor - PROMS will get stuck in a loop (hang) while placing RO.FST information in the plant database (loading RO's) when Unit Values contain brackets. Example is Point Beach data.' (#523) from B2025-015 into Development
good for testing phase
2025-02-20 10:08:52 -05:00
9980504c47 B2025-015 RO Editor - PROMS will get stuck in a loop (hang) while placing RO.FST information in the plant database (loading RO's) when Unit Values contain brackets. Example is Point Beach data.
Some of Point Beach RO's have curly braces in the RO return value for the units in P/C.  Found this on some (5-7) Annunciator RO values.  The definition of the return value (multiple return values) uses curly braces so PROMS cannot distinguish between brackets being part of a unit value or part of the format for multiple return values.

Equipment Designation, Main Steam (MS), Annunciators have examples of return values with curly braces.  Look at the Referenced Object Definition on the Annunciators tree node for the definition of the return value.
2025-02-20 10:03:05 -05:00
626960da9f Merge pull request 'C2025-014 The zoom setting on step level bookmarks in generated PDFs will now jump to the page containing the step (like it does when a section bookmark is selected) instead of zooming in on the step.' (#522) from C2025-014_PDF_Step_BckMrk_Zoom into Development
Looks Good - Ready for QA testing
2025-02-18 15:52:52 -05:00
535728b982 C2025-014 The zoom setting on step level bookmarks in generated PDFs will now jump to the page containing the step (like it does when a section bookmark is selected) instead of zooming in on the step. 2025-02-18 15:39:55 -05:00
ace9672a2e Merge pull request 'B2025-019 RO Editor - When selecting an RO Definition, clicking the X in the corner or selecting Cancel prompts you to verify you want to close without saving changes when no changes were made if there is Parent/Child & applicability was never set for …' (#521) from B2025-019 into Development
good for testing phase (remember to build the Reference Objects project)
2025-02-18 15:38:10 -05:00
05a13861ac B2025-019 RO Editor - When selecting an RO Definition, clicking the X in the corner or selecting Cancel prompts you to verify you want to close without saving changes when no changes were made if there is Parent/Child & applicability was never set for the in-use fields. 2025-02-18 15:21:19 -05:00
24374b85c1 Merge pull request 'C2024-038 - Bringing date control to the front so left side of box shows' (#520) from C2024-038_v2 into Development
good for testing phase
2025-02-18 09:01:05 -05:00
8c358f1e3c C2024-038 - Bringing date control to the front so left side of box shows 2025-02-18 07:42:35 -05:00
289285f517 Merge pull request 'F2025-002 Per customer, remove the newly added Action Verbs from the PROMS ReplaceWords list.' (#519) from F2025-002_Farley into Development
Format only change.  Good for testing.
2025-02-17 15:12:22 -05:00
3ee9e0f4eb F2025-002 Per customer, remove the newly added Action Verbs from the PROMS ReplaceWords list. 2025-02-17 15:12:06 -05:00
d6c924a51f Merge pull request 'B2025-016 – Quick Print Shortcut Key' (#518) from B2025-016 into Development
good for testing phase
2025-02-17 08:41:17 -05:00
3a739c5b64 B2025-016 – Quick Print Shortcut Key
Found during Functional Testing:
Using "ALT R" shortcut key shows that Quick Print PDF & Create PDF both then have "P" as their shortcut. Kept Create PDF/Print as Ctrl-P. Changed Quick Print to be shortcut of Ctrl-Q.
2025-02-17 08:21:16 -05:00
3564f4ba8e Merge pull request 'C2024-038 PROMS – Summary of Changes report generation enhancements' (#517) from C2024-038 into Development
Good for testing phase
2025-02-14 15:21:08 -05:00
5ad9d81cc1 C2024-038 PROMS – Summary of Changes report generation enhancements
This is an upgrade item to add a method to exclude annotations and a way run the summary of changes report from a specific date.
2025-02-14 15:10:40 -05:00
c7bdcf0104 Merge pull request 'Development' (#516) from Development into master
Merging changes from development into master after successful testing
2025-02-11 15:25:38 -05:00
0292634374 Merge pull request 'We are reverting back to the last DotNetBar install. We found issues on the developer side of maintaining the dialogs and forms in PROMS.' (#515) from OrgDotNetBar into Development
Software Development Environment update.  No source control document  needed.
2025-02-11 15:06:39 -05:00
d4418b8d8a We are reverting back to the last DotNetBar install. We found issues on the developer side of maintaining the dialogs and forms in PROMS. 2025-02-11 15:02:58 -05:00
a33f136e77 Merge pull request 'B2025-011-Global-search-is-not-finding-question-marks' (#514) from B2025-011-Global-search-is-not-finding-question-marks into Development
good for testing phase
2025-02-11 09:07:12 -05:00
f85f8e9e2c Merge pull request 'B2025-013 PROMS –Admin Tool Tree Behavior' (#513) from B2025-013 into Development
good for testing phase
2025-02-10 11:04:07 -05:00
01541c9e0d B2025-013 PROMS –Admin Tool Tree Behavior 2025-02-10 10:57:01 -05:00
4bfffc945a Merge remote-tracking branch 'origin/Development' into B2025-011-Global-search-is-not-finding-question-marks 2025-02-10 10:23:24 -05:00
df026499d5 Merge pull request 'Development' (#512) from Development into master
Merging all changes from development into master after successful testing.
2025-02-10 09:20:43 -05:00
16509c2eab B2025-011-Global-search-is-not-finding-question-marks 2025-02-09 22:44:01 -05:00
bc1f85b657 Merge pull request 'DotNet 4.8.1 build of DotNetBar' (#511) from DotNetBar_net4.8.1 into Development
.Net 4.8.1 build of Dot Net Bar's dll
2025-02-07 10:36:55 -05:00
6b0a5d60f4 DotNet 4.8.1 build of DotNetBar 2025-02-07 10:35:23 -05:00
33439b63a0 Merge pull request 'Using Net 4.8.1 build of CSLA' (#510) from CLSA481Build into Development
.Net 4.8.1 build of CSLA.dll.
testing will be done during User Manual Updates and baseline print testing.
2025-02-06 16:04:27 -05:00
bb24d1207d Using Net 4.8.1 build of CSLA 2025-02-06 15:57:41 -05:00
8fc477ec04 Merge pull request 'B2025-014 PROMS – RO Update Admin Tool Error when updating RO containing carats/deltas' (#509) from B2025-014 into Development
good for testing phase
2025-02-05 14:03:18 -05:00
bf06c9e14f B2025-014 PROMS – RO Update Admin Tool Error when updating RO containing carats/deltas
While testing an update for C2025-0011, using BNPP data and ROs, the update ro values crashes at the next to the last procedure set which is folder called "PROMS Tests." It crashes with a null reference as it is not able to detect the format. This is to change this to use the “ActiveFormat” of the Working Folder instead of utilizing “MyFormat”.
2025-02-05 13:34:18 -05:00
a3aa4157b8 Merge pull request 'Development' (#508) from Development into master
Merging all changes through B2025-012 from development into master after successful testing.
2025-02-05 10:50:35 -05:00
5a263107da Merge pull request 'B2025-012 PROMS – Searching Step Elements – All Step Types' (#507) from B2025-012 into Development
good for testing phase
2025-02-05 10:01:13 -05:00
d30bb2e329 B2025-012 PROMS – Searching Step Elements – All Step Types
When searching for step elements (the Find Selected Step Elements option is selected) and "All Types." Is selected for step types, you incorrectly get the "No Types Selected" message box when clicking on search.
2025-02-05 08:38:18 -05:00
8248bd8e47 Merge pull request 'C2025-011 PROMS – RO Update Admin Tool Memory Enhancements' (#506) from C2025-011 into Development
good for the testing phase
2025-02-04 13:47:24 -05:00
378653c536 C2025-011 PROMS – RO Update Admin Tool Memory Enhancements
The purpose of this upgrade is to improve the user experience when using the Admin tool to Update ROs. Currently for larger RO dbs (like Barakah) we can run up against memory constraints that do not allow all the ROs to be updated at one time. This is based upon some initial resource where some places were identified where we could improve memory usage.  Some of these should benefit PROMS as a whole while others will be specific to the RO Update option in Admin Tools.
2025-02-04 13:23:21 -05:00
f2d330bd0e Merge pull request 'F2025-001 Barakah provided us with format changes to add more signoffs to the "BNPP Single Column Format - 2021" in which they had made.' (#505) from F2025-001_BNPP into Development
format only change - ready for testing
2025-02-03 13:41:58 -05:00
c1c93cbdc4 F2025-001 Barakah provided us with format changes to add more signoffs to the "BNPP Single Column Format - 2021" in which they had made. 2025-02-03 13:40:18 -05:00
8f3268e1bc Merge pull request 'Development' (#504) from Development into master
Merging all changes from development into master after successful testing.
2025-01-30 15:55:02 -05:00
47a14e143e Merge pull request 'C2019-025_Ability-to-Toggle-Replace-Words-3' (#503) from C2019-025_Ability-to-Toggle-Replace-Words-3 into Development
good for testing phase
2025-01-30 09:26:20 -05:00
b7aa85f4fc C2019-025_Ability-to-Toggle-Replace-Words-3 2025-01-30 09:22:51 -05:00
90e25f3fcf C2019-025_Ability-to-Toggle-Replace-Words-3 2025-01-30 09:09:39 -05:00
d67e81d8a6 Merge pull request 'C2025-005 PROMS – Searching Step Elements' (#502) from C2025-005 into Development
good for testing phase
2025-01-29 15:31:59 -05:00
057915baaa C2025-005 PROMS – Searching Step Elements
When searching for step elements (the Find Selected Step Elements option is selected) and multiple procedure sets are selected, but the procedure sets use different formats, PROMS puts a message in the Results area that says "folders selected contain multiple formats". Need to expand this messaging to provide more clear information regarding which formats are causing the issue, so that they can more easily decide which sets to de-select rather than doing so randomly.  There is also a refresh issue where deselecting everything, it will not always refresh properly.
2025-01-29 15:26:29 -05:00
fe268b6122 Merge pull request 'C2019-025_Ability-to-Toggle-Replace-Words-2' (#501) from C2019-025_Ability-to-Toggle-Replace-Words-2 into Development
good for testing phase
2025-01-29 15:04:09 -05:00
ca61597863 C2019-025_Ability-to-Toggle-Replace-Words-2 2025-01-29 14:21:14 -05:00
a04def360d Merge pull request 'B2025-010 PROMS – Change ID Issues' (#500) from B2025-010 into Development
good for testing phase
2025-01-28 09:05:28 -05:00
5e43a8501b B2025-010 PROMS – Change ID Issues
Removing the change id via backspaces in the change id box in the step properties panel can cause PROMS to crash. Also, it doesn’t always remove the change id properly. Changing this to instead of updating every time text changes in the box, adding a save button. Also, adding some null exception error handling.
2025-01-27 16:09:19 -05:00
e893264075 Merge pull request 'C2019-025_Ability-to-Toggle-Replace-Words' (#499) from C2019-025_Ability-to-Toggle-Replace-Words into Development
OK for testing phase
2025-01-27 15:51:01 -05:00
cf20704811 C2019-025_Ability-to-Toggle-Replace-Words 2025-01-27 15:45:09 -05:00
37c5b23a86 C2019-025_Ability-to-Toggle-Replace-Words 2025-01-27 13:38:48 -05:00
82d8fe6e17 Merge pull request 'B2025-005 PROMS - Change Reports - Invalid Transitions showing Incorrectly' (#498) from B2025-005 into Development
good for testing phase
2025-01-24 15:53:37 -05:00
4ca3697845 B2025-005 PROMS - Change Reports - Invalid Transitions showing Incorrectly 2025-01-24 15:29:07 -05:00
71130bd26b C2019-025_Ability-to-Toggle-Replace-Words 2025-01-24 10:12:43 -05:00
37626d8f45 Merge pull request 'C2025-008 RO Editor – Remove redundant Save Failed message box' (#497) from C2025-008 into Development
Good for testing phase
2025-01-24 08:36:04 -05:00
f95369d3a4 C2025-008 RO Editor – Remove redundant Save Failed message box 2025-01-24 08:02:24 -05:00
aa00891f8e Merge pull request 'B2025-008 PROMS - Display RO Step Properties - RO Tables' (#496) from B2025-008 into Development
good for testing phase
2025-01-23 16:13:56 -05:00
d44f9ba2b6 B2025-008 PROMS - Display RO Step Properties - RO Tables 2025-01-23 15:50:52 -05:00
c3b7b1e5a4 Merge pull request 'B2025-007 RO Editor – RO Figure Default File extension' (#495) from B2025-007 into Development
good for testing phase
2025-01-23 11:06:24 -05:00
f3309e4a40 B2025-007 RO Editor – RO Figure Default File extension 2025-01-23 11:02:15 -05:00
8fa059c186 Merge pull request 'C2025-007 ROEditor - PROMPT to Confirm Deletion' (#494) from C2025-007 into Development
good for testing phase
2025-01-22 13:31:24 -05:00
96e61aea2b C2025-007 ROEditor - PROMPT to Confirm Deletion
When deleting a group or an RO in the RO Editor, consider adding a prompte for the user asking if they are sure they want to delete the ro/group.  Perhaps also add text to the message saying they may want to consider creating a zip file of the RO folder prior to deleting ROs/groups.
2025-01-22 12:45:27 -05:00
565779c9c8 Merge pull request 'B2025-009 RO Editor - Disable the Save As button if it is a new RO that has not been saved yet.' (#493) from B2025-009 into Development
change ready for testing
2025-01-22 12:01:04 -05:00
b4ccd682c3 B2025-009 RO Editor - Disable the Save As button if it is a new RO that has not been saved yet.
Adding a new RO:  when you click Save As, you get the Problem Saving Data message box. Should only be able to “Save As” if it has already been previously saved.
2025-01-22 11:57:57 -05:00
dba1331556 Merge pull request 'B2025-004 Remove dependency on stored procedure (GetDisplayTabdata).' (#492) from B2025-004_v2 into Development
changes good for testing phase
2025-01-22 10:39:24 -05:00
8803ae2274 B2025-004 Remove dependency on stored procedure (GetDisplayTabdata).
-- Found during testing that needed a few additional items that needed to not create hard errors
2025-01-22 10:35:44 -05:00
69d09b7fc2 Merge pull request 'B2025-004 Remove dependency on stored procedure (GetDisplayTabdata).' (#491) from B2025-004 into Development
good for testing phase
2025-01-22 08:25:26 -05:00
8ddfc8654e Merge pull request 'C2025-006_B2025-006 - C2025-006 RO Editor Figure wording update, B2025-006 RO Editor Figure Height or Width warning message update' (#490) from C2025-006_B2025-006 into Development
good for testing phase
2025-01-22 08:19:05 -05:00
7a3243e882 B2025-004 Remove dependency on stored procedure (GetDisplayTabdata). 2025-01-22 06:59:03 -05:00
4fc3b89e06 C2025-006_B2025-006 - C2025-006 RO Editor Figure wording update, B2025-006 RO Editor Figure Height or Width warning message update 2025-01-22 06:26:48 -05:00
a17419ac12 Merge pull request 'C2025-003 Enhanced Copy/Paste Upgrade - Add ability to copy/paste over enhanced master documents' (#487) from C2025-003 into Development
ready for testing phase
2025-01-21 10:48:00 -05:00
5721d440e9 Merge branch 'master' of https://git.volian.com/Volian/SourceCode 2025-01-21 10:42:15 -05:00
505c396283 Merge pull request 'Development' (#489) from Development into master
Merging from development into master after successful testing.
2025-01-21 10:41:15 -05:00
88905132e7 Merge branch 'Development' of https://git.volian.com/Volian/SourceCode into Development 2025-01-21 10:40:06 -05:00
111bed58d6 Merge pull request 'B2025-003 Chronology/Summary of Changes Reports' (#488) from B2025-003 into Development
Reviewed-on: #488

due to GIT restore from backup
2025-01-21 10:31:21 -05:00
bed61324d6 C2025-003 Enhanced Copy/Paste Upgrade - Add ability to copy/paste over enhanced master documents 2025-01-20 14:43:54 -05:00
643e6bc94f Merge pull request 'Development' (#486) from Development into master
Merging all items through B2025-003 from development in master after successful testing.
2025-01-09 15:02:16 -05:00
1a889352b8 Merge pull request 'B2025-003 Chronology/Summary of Changes Reports' (#485) from B2025-003 into Development
ready for testing phase
2025-01-09 11:14:22 -05:00
5bba126a36 B2025-003 Chronology/Summary of Changes Reports 2025-01-09 11:08:30 -05:00
e01b955d46 Merge pull request 'F2024-088 - Per customer’s request, removed “Using”, “Faulted”, “Intact”, “Normal”, “On”, “Off”, “Locally”, “Manually”, “Fall”, “Rise”, and “Ruptured” from the ReplaceWords list' (#484) from F2024-088_FNP into Development
Format only change.  ready for testing phase
2024-12-17 09:48:30 -05:00
e3431b0e1e F2024-088 - Per customer’s request, removed “Using”, “Faulted”, “Intact”, “Normal”, “On”, “Off”, “Locally”, “Manually”, “Fall”, “Rise”, and “Ruptured” from the ReplaceWords list 2024-12-17 09:46:40 -05:00
b6d646b910 Merge pull request 'F2024-086 In the PROMS Manual format in the Attachments (Step Editor) With Border section type, the page number needs centered horizontally on the page (it's located between the section number and section title.' (#483) from F2024-086 into Development
good for testing phase
2024-12-12 08:44:08 -05:00
bb679a2790 F2024-086 In the PROMS Manual format in the Attachments (Step Editor) With Border section type, the page number needs centered horizontally on the page (it's located between the section number and section title. 2024-12-12 08:36:29 -05:00
e3af0a6426 Merge pull request 'B2024-094 - Carats (as Deltas) print as question marks in tables when unit <u> is used in RO Definition Value' (#482) from B2024-094 into Development
good for testing phase
2024-12-12 08:33:12 -05:00
b2108b9e5f B2024-094 - Carats (as Deltas) print as question marks in tables when unit <u> is used in RO Definition Value 2024-12-11 15:35:29 -05:00
76502e6d97 Merge pull request 'Development' (#481) from Development into master
Merging all changes through F2024-087 after successful testing.
2024-12-11 11:52:34 -05:00
d100002107 Merge pull request 'F2024-087 - Fixes printing sub-sections that go from continuous (single column sub-sections) to a separate (two column sub-section) so that the two column sub-section starts at the top of the page.' (#480) from F2024-097_Farley into Development
format only - good for testing phase
2024-12-11 11:14:44 -05:00
afd61303c5 F2024-087 - Fixes printing sub-sections that go from continuous (single column sub-sections) to a separate (two column sub-section) so that the two column sub-section starts at the top of the page. 2024-12-11 11:07:30 -05:00
d1c3e81a38 Merge pull request 'B2024-096 In the Ro Editor, allow <u> for a field name in the Referenced object Definition Return Value.' (#479) from B2024-096 into Development
good for testing phase
2024-12-10 09:00:22 -05:00
46419edfee B2024-096 In the Ro Editor, allow <u> for a field name in the Referenced object Definition Return Value. 2024-12-10 08:36:30 -05:00
81c91d7866 Merge pull request 'C2024-037 Enhanced Print Section so that it can now be utilized for Sections that contain subsections.' (#478) from C2024-037 into Development
good for testing phase
2024-12-09 16:07:53 -05:00
34ee092919 C2024-037 Enhanced Print Section so that it can now be utilized for Sections that contain subsections.
Farley uses subsections in some of their AOP procedures.   The "Print Section" feature did not work for these sections - instead returning a message as if the pdf was already open.
2024-12-09 15:24:34 -05:00
d07344a88a Merge pull request 'B2024-095 In Admin Tools, added minimum heights to the left side panels above selecting items in the trees. Previously when the windows were resized the trees would overlap with buttons and notes.' (#477) from B2024-095 into Development
good for testing phase
2024-12-09 10:34:58 -05:00
66ae1c632b B2024-095 In Admin Tools, added minimum heights to the left side panels above selecting items in the trees. Previously when the windows were resized the trees would overlap with buttons and notes. 2024-12-09 08:00:15 -05:00
7cc7b71edd Merge pull request 'B2024-067 Deleting Folders through Admin Tools missing some folders' (#476) from B2024-067 into Development
ready for testing phase
2024-12-05 15:51:32 -05:00
a223dfd463 B2024-067 Deleting Folders through Admin Tools missing some folders 2024-12-05 15:27:46 -05:00
61e8bc5ffa Merge pull request 'B2024-003_B2023-113_B2024-093 Updating RO Values inside a text Grid, adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. This also fixes restoring a deleted RO table column that has a hyphen in …' (#475) from B2024-003_B2023-113_B2024-093 into Development
good for testing phase
2024-12-03 15:22:47 -05:00
bba52a736a B2024-003_B2023-113_B2024-093 Updating RO Values inside a text Grid, adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. This also fixes restoring a deleted RO table column that has a hyphen in it. Also, Dashes/Hyphens and Carets in RO TABLES were behaving differently in different data sets due to different fonts – this fixes so that carats when ConvertCaretToDelta is set in the format, will properly restore/store as Deltas. 2024-12-03 15:12:04 -05:00
c5d575a019 Merge pull request 'F2019-011 Wide step tabs were printing into text. Shifted Left Justification slightly (roughly 2 characters) to account for these / this spacing.' (#474) from F2019-011 into Development
ok for testing phase
2024-11-27 09:28:22 -05:00
08f8441aca F2019-011 Wide step tabs were printing into text. Shifted Left Justification slightly (roughly 2 characters) to account for these / this spacing. 2024-11-27 09:19:42 -05:00
6bf116cbef Merge pull request 'B2023-095_U2022-004 - When Copy/Pasting Symbols, some of the symbols paste in an incorrect font' (#473) from B2023-095_U2022-004 into Development
good for testing phase
2024-11-25 14:51:35 -05:00
cc96b3fa5b B2023-095_U2022-004 - When Copy/Pasting Symbols, some of the symbols paste in an incorrect font 2024-11-25 14:44:50 -05:00
b489452bd1 Merge pull request 'B2023-029 - Added format flag to Continuous Action Note and Continuous Action Caution so that the check box to include on the generated Continuous Action Summary is automatically checked' (#472) from B2023-039_bwd_byr into Development
format only change.
Ready for testing phase
2024-11-22 14:56:17 -05:00
fa4e3997e4 B2023-029 - Added format flag to Continuous Action Note and Continuous Action Caution so that the check box to include on the generated Continuous Action Summary is automatically checked 2024-11-22 14:55:12 -05:00
7659cbbee6 Merge pull request 'B2023-074 - Fixed printing a section title, via the section properties check box, on a two-column step editor section.' (#471) from General_Debugging into Development
minor code change - no review needed.
OK for testing phase
2024-11-22 10:20:22 -05:00
548b845f62 B2023-074 - Fixed printing a section title, via the section properties check box, on a two-column step editor section. 2024-11-22 10:10:57 -05:00
4f733656a0 Merge pull request 'F2024-085 - Added a Conditional Time Critical Action high level step type to the EOP and AOP formats' (#470) from F2024-085_BVPS_ContTimeAction into Development
format only changes
2024-11-20 09:12:29 -05:00
f4ef244a10 F2024-085 - Added a Conditional Time Critical Action high level step type to the EOP and AOP formats 2024-11-20 09:10:46 -05:00
839000d48c Merge pull request 'B2024-003_ B2023-113 Updating RO Values inside a text Grid, adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. This also fixes restoring a deleted RO table column that has a hyphen in it.' (#469) from B2024-003_B2023_113_GIT into Development
good for testing phase
2024-11-18 16:24:13 -05:00
bcb8f419ee B2024-003_ B2023-113 Updating RO Values inside a text Grid, adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. This also fixes restoring a deleted RO table column that has a hyphen in it. 2024-11-18 16:17:07 -05:00
059c399240 Merge pull request 'B2021-094 - Fixed shortcut keystroke usage for the GoTo button <Shift><Ctrl><G> when used multiple times' (#468) from B2021-094_keystroke4GoTo into Development
Looks good - ready for QA
2024-11-18 14:59:13 -05:00
13b3cd6bc4 B2021-094 - Fixed shortcut keystroke usage for the GoTo button <Shift><Ctrl><G> when used multiple times 2024-11-18 14:54:34 -05:00
3cd4f4c5d9 Merge pull request 'C2024-028 Add an enhancement to Admin Tools -> Refresh Transitions. Transitions with bad links that cannot be auto-fixed, will now add an annotation of “Bad Transition Link” (which can then be searched for and manually resolved.)' (#467) from C2024-028 into Development
good for testing phase
2024-11-15 09:51:23 -05:00
02b20df652 C2024-028 Add an enhancement to Admin Tools -> Refresh Transitions. Transitions with bad links that cannot be auto-fixed, will now add an annotation of “Bad Transition Link” (which can then be searched for and manually resolved.) 2024-11-15 09:23:27 -05:00
416bdf16e0 Merge pull request 'B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher.' (#466) from B2021-043 into Development
good for testing phase
2024-11-13 14:40:33 -05:00
75a4f66714 B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. 2024-11-13 14:10:39 -05:00
a5b9c26a97 Merge pull request 'F2024-078 - Adjust the spacing before and after the Note tab, along with the blank space (line) at the bottom of the Note box per the example supplied by the customer. Also made similar adjustments to the Caution tab and box.' (#465) from F2024-078_BVNoteSpacing into Development
Looks good - Ready for QA
2024-11-11 16:35:56 -05:00
0aa476d9dd F2024-078 - Adjust the spacing before and after the Note tab, along with the blank space (line) at the bottom of the Note box per the example supplied by the customer. Also made similar adjustments to the Caution tab and box. 2024-11-11 15:56:55 -05:00
851a0b3810 Merge pull request 'Development' (#464) from Development into master
Merging all items through B2024-092 from development into master after successful testing.
2024-11-11 11:39:01 -05:00
0f4eec1df6 Merge pull request 'B2024-092 Add Initial Line/Ability to Disable to UI for South Texas' (#463) from B2024-092 into Development
good for testing phase
2024-11-11 08:28:36 -05:00
4bc73f847c B2024-092 Add Initial Line/Ability to Disable to UI for South Texas 2024-11-11 07:15:02 -05:00
e1271c16d9 Merge pull request 'B2024-090 If multiple tabs are left open, and Find is clicked before clicking on a tab, PROMS would crash.' (#462) from B2024-090 into Development
good for testing phase
2024-11-08 15:43:30 -05:00
c7d2140e16 B2024-090 If multiple tabs are left open, and Find is clicked before clicking on a tab, PROMS would crash. 2024-11-08 15:37:49 -05:00
ac6ee6ff83 Merge pull request 'C2024-022 Add option to select by unit when generating a Time Critical Action Summary from the ribbon in a Parent document.' (#461) from C2024-022 into Development
good for testing phase
2024-11-07 15:24:47 -05:00
1507cf31ce C2024-022 Add option to select by unit when generating a Time Critical Action Summary from the ribbon in a Parent document. 2024-11-07 15:06:38 -05:00
aad04647ac Merge pull request 'C2024-021 Update the tool tip on the Time Critical Action Summary option (Step Properties panel) to reflect the Time Critical Action Summary text rather than the Continuous Action Summary text.' (#460) from C2024-021 into Development
good for testing phase
2024-11-07 10:54:58 -05:00
934d3977d8 C2024-021 Update the tool tip on the Time Critical Action Summary option (Step Properties panel) to reflect the Time Critical Action Summary text rather than the Continuous Action Summary text. 2024-11-07 10:08:26 -05:00
03b0e52bef Merge pull request 'B2024-064 Improve user experience by providing more descriptive wording when cannot change the Applicability of a Step/Section.' (#459) from B2024-064 into Development
good for testing phase
2024-11-07 09:20:47 -05:00
1da2b8e87c B2024-064 Improve user experience by providing more descriptive wording when cannot change the Applicability of a Step/Section. 2024-11-07 09:13:40 -05:00
e3d16142ac Merge pull request 'C2024-025 Remove the tall box characters from the search results.' (#458) from C2024-025 into Development
Good for testing phase
2024-11-07 08:42:21 -05:00
b972e40a28 C2024-025 Remove the tall box characters from the search results. 2024-11-07 08:26:26 -05:00
c508255ab3 Merge pull request 'C2024-026 Add feature to the transitions panel to allow user to hold currently selected procedure/set in the panel.' (#457) from C2024-026 into Development
good for testing phase
2024-11-05 13:21:31 -05:00
e9ec884eb9 C2024-026 Add feature to the transitions panel to allow user to hold currently selected procedure/set in the panel. 2024-11-05 10:59:01 -05:00
592d28e898 Merge pull request 'B2024-080 Add Image Thumbnails to Find Submenu items to be consistent with elsewhere in the application' (#456) from B2024-080 into Development
Good for testing phase
2024-11-05 10:53:06 -05:00
b826fa6a20 B2024-080 Add Image Thumbnails to Find Submenu items to be consistent with elsewhere in the application 2024-11-05 10:48:52 -05:00
74c2a303da Merge pull request 'B2024-089 Loic to clean up transitioning to a section that does not have a section number. Also added and updated comments.' (#455) from B2024-089 into Development
Looks good to me.
Merging to Development - Ready for QA.
2024-11-04 16:46:34 -05:00
dcf50073e7 B2024-089 Loic to clean up transitioning to a section that does not have a section number. Also added and updated comments. 2024-11-04 14:39:41 -05:00
fd8dbb4c8b Merge pull request 'Development' (#454) from Development into master
Merging all changes from development into master after successful testing.
2024-11-01 14:18:00 -04:00
375871012c Merge pull request 'F2024-084 - Adjusted tab spacing in Beaver Valley’s AOP format and added a space after the bullet in the Bulleted High-level step in the Beaver Valley SAMG format. For the AOP format needed to remove the general tab format setting TabPtsPerChar (tha…' (#453) from F2024-084 into Development
Format only change
2024-11-01 10:15:00 -04:00
b7b67cce69 F2024-084 - Adjusted tab spacing in Beaver Valley’s AOP format and added a space after the bullet in the Bulleted High-level step in the Beaver Valley SAMG format. For the AOP format needed to remove the general tab format setting TabPtsPerChar (that affects all of the sub-step tab spacing) in order to have all of the AOP sub-step tab spacing the same as the EOP format. 2024-11-01 10:12:52 -04:00
6c22bff1fd Merge pull request 'C2024-034 RO Editor – Enhancement for when “Standard Fields” are modified.' (#452) from C2024-034 into Development
good for testing phase
2024-10-31 15:49:33 -04:00
0b12805d4a C2024-034 RO Editor – Enhancement for when “Standard Fields” are modified. 2024-10-31 15:44:28 -04:00
4bac1a4628 Merge pull request 'C2024-035 RO Editor – Enhancement to Handle renaming of Setpoint Value.' (#451) from C2024-035 into Development
good for testing phase
2024-10-31 15:17:38 -04:00
2cf164c445 C2024-035 RO Editor – Enhancement to Handle renaming of Setpoint Value. 2024-10-31 15:11:04 -04:00
4ffd994c5e Merge pull request 'Development' (#450) from Development into master
Merging all development items into master after successful testing.
2024-10-31 09:11:59 -04:00
11904e177b Merge pull request 'B2024-077 When searching Referenced Objects Reports, pick the RO and select a procedure set and the selection panel refreshes and you lose your selection. If the set has to be selected first then it should be at the top of the report panel.' (#449) from B2024-077 into Development
good for testing phase
2024-10-29 16:13:51 -04:00
527e6b5053 B2024-077 When searching Referenced Objects Reports, pick the RO and select a procedure set and the selection panel refreshes and you lose your selection. If the set has to be selected first then it should be at the top of the report panel.
Also fixed a small ancillary typo that I found while finding this.
2024-10-29 15:46:12 -04:00
053ebca267 Merge pull request 'C2024-033 RO Editor – Clarify wording presented to user when utilizing new Move RO feature in RO Editor.' (#447) from C2024-033 into Development
ready for testing phase
2024-10-29 09:54:06 -04:00
5e7fae9d47 Merge pull request 'F2024-082 - Added Dump, Modulate, Observe, Return, Proceed, Direct to the replace words list in all of the Farley formats' (#448) from F2024-082 into Development
format only change
2024-10-29 09:41:02 -04:00
0e4ce99612 F2024-082 - Added Dump, Modulate, Observe, Return, Proceed, Direct to the replace words list in all of the Farley formats 2024-10-29 09:40:00 -04:00
3c75637752 C2024-033 RO Editor – Clarify wording presented to user when utilizing new Move RO feature in RO Editor. 2024-10-29 07:54:50 -04:00
fb890ded1f Merge pull request 'C2024-031 Option to Disable reopen closed tabs on PROMS reentry' (#445) from C2024-031 into Development
good for testing phase
2024-10-28 14:40:05 -04:00
4399f31a83 Merge pull request 'F2024-079 - Set the flag to not uppercase the procedure and section titles in transitions in the background formats to make it consistent with the other Beaver Valley formats.' (#446) from F2024-079 into Development
format only change
2024-10-28 14:24:51 -04:00
ca4b21e593 F2024-079 - Set the flag to not uppercase the procedure and section titles in transitions in the background formats to make it consistent with the other Beaver Valley formats. 2024-10-28 13:59:14 -04:00
23a4edb610 C2024-031 Option to Disable reopen closed tabs on PROMS reentry 2024-10-28 13:28:35 -04:00
accc1c622c Merge pull request 'F2024-077 - Made the spacing between bullet tabs the step text consistent for bulleted sub-steps types and for multiple Cautions, Notes types' (#444) from F2024-077_BVtabs into Development
format only changes
2024-10-25 15:05:17 -04:00
e50ea6a5db F2024-077 - Made the spacing between bullet tabs the step text consistent for bulleted sub-steps types and for multiple Cautions, Notes types 2024-10-25 15:03:41 -04:00
04ce6f55db Merge pull request 'CSM B2024-087 Fix RO Editor Inconsistencies' (#443) from B2024-087 into Development
ready for testing phase
2024-10-25 14:39:24 -04:00
f0493e60d8 CSM B2024-087 Fix RO Editor Inconsistencies
Refresh issue in RO Definitions.  Modify an In Use field item that is not one of the Standard items, choose Continue, choose OK in the Text Definition Field. when prompted if want to Update Local or Generic definitions:

1. Prompt should contain table name (previously was not for Setpoint items)

2. If Select "Yes", Should refresh to new field name when return to previous screen / click ok to go back to RO Definition.
2024-10-25 14:33:20 -04:00
13edc9c9ff Merge pull request 'F2024-080 Add Initial Line/Ability to Disable to UI for South Texas' (#442) from F2024-080 into Development
good for testing phase.
2024-10-25 10:12:10 -04:00
fd0ea4404b F2024-080 Add Initial Line/Ability to Disable to UI for South Texas 2024-10-25 09:19:20 -04:00
df9d0f908a Merge pull request 'C2024-030 RO Editor Enhancement to include table name / explain the scope of changing a field definition Local vs Generic' (#441) from C2024-030 into Development
good for testing phase
2024-10-24 09:08:42 -04:00
779394ffd6 C2024-030 RO Editor Enhancement to include table name / explain the scope of changing a field definition Local vs Generic
When updating a field in a RO Definition, there is a prompt asking if changes should be Local or Generic --- Should change wording to explain that Local is local to that table (and include Table name in that wording)
2024-10-24 07:43:00 -04:00
a230ecef9b Merge pull request 'Just added space to a comment to force a new check-in of these Farely fomrat files' (#440) from General_Debugging into Development
no testing needed.  This is to try to resolve a Git and build issue with Farley format files on developer machines.
2024-10-23 16:42:06 -04:00
061bcfdc0f Just added space to a comment to force a new check-in of these Farely fomrat files 2024-10-23 16:37:04 -04:00
aced10498b Merge pull request 'B2024-084 Fix Refresh Issue in RO Definitions.' (#439) from B2024-084 into Development
good for testing phase
2024-10-23 16:09:42 -04:00
cd963d01e4 B2024-084 Fix Refresh Issue in RO Definitions.
Modify an In Use field item, choose Continue, choose OK in the Text Definition Field.  Hit Cancel in the next two windows, then open the RO Definition back up and the change is still there in the "In Use" column but not the Menu Value.    Close the RO Editor and re-open and the change was now gone as it's supposed to be.
2024-10-23 15:54:20 -04:00
458dd5fff4 Merge pull request 'B2024-085 Fix Object Reference Error when Getting Schema for a RO database in SQL' (#438) from B2024-085 into Development
good for testing phase
2024-10-23 14:56:21 -04:00
0c342fa188 B2024-085 Fix Object Reference Error when Getting Schema for a RO database in SQL
After converting the Robinson ROs to SQL, upon changing an In Use field and clicking Continue, an "Error on Schema" message box displayed with an unhandled error exception.
2024-10-23 14:07:20 -04:00
43b13443ab Merge pull request 'C2024-027 RO Editor – Add additional feature to allow Cut/Paste (Moving) a RO within the same table.' (#437) from CSM-C2024-027 into Development
Good for testing phase
2024-10-23 13:38:10 -04:00
c867d4e4b1 C2024-027 RO Editor – Add additional feature to allow Cut/Paste (Moving) a RO within the same table. 2024-10-23 13:20:20 -04:00
0f541142cc Merge pull request 'F2024-081- Removed the extra blank line after the Alternate High Level Step type. This was mistakenly changed during format cleanup. It is now restored to what it should be.' (#436) from F2024-081_Catawba into Development
Format only changes.
2024-10-23 12:01:19 -04:00
b0c55d09b0 F2024-081- Removed the extra blank line after the Alternate High Level Step type. This was mistakenly changed during format cleanup. It is now restored to what it should be. 2024-10-23 11:59:55 -04:00
ee71431210 Merge pull request 'F2024-076 - Added a line before the continue message in the background formats. Centered the bottom continue message for the step editor sections – all formats' (#435) from F2024-076_BV_ContinueMsg into Development
format only changes
2024-10-23 11:08:00 -04:00
a8196db676 F2024-076 - Added a line before the continue message in the background formats. Centered the bottom continue message for the step editor sections – all formats 2024-10-23 11:06:31 -04:00
8dc78d49eb Merge pull request 'Delete .gitattributes' (#434) from remove_gitattributes into Development
changes are good. This should allow us to compare format files again.
2024-10-17 09:27:10 -04:00
3999d1c49b Merge pull request 'C2020-049-Add-the-ability-for-PROMS-to-remember-open-procedure-tabs-fixed-print' (#433) from C2020-049-Add-the-ability-for-PROMS-to-remember-open-procedure-tabs-fixed-print into Development
good for testing phase
2024-10-17 09:25:22 -04:00
aceb928dba Delete .gitattributes
remove gitattributes file
2024-10-17 09:17:01 -04:00
f17db695d3 C2020-049-Add-the-ability-for-PROMS-to-remember-open-procedure-tabs-fixed-print 2024-10-16 16:23:31 -04:00
214dd8ec08 Merge pull request 'GIT_ATTRIBUTE_FILE - adjusting GIT settings so should be able to see diff of xml files in GIT (and not just Visual Studio history)' (#432) from GIT_ATTRIBUTE_FILE2 into Development
change approved - no testing needed for this.
2024-10-15 09:23:27 -04:00
2f974d7b52 Merge pull request 'C2024-029 RO Editor - Referenced Object Definition Form - Add check if items changed before prompting to possibly save' (#431) from C2024-029 into Development
good for testing phase
2024-10-15 09:22:16 -04:00
9f1dce896f GIT_ATTRIBUTE_FILE - adjusting GIT settings so should be able to see diff of xml files in GIT (and not just Visual Studio history) 2024-10-15 08:58:15 -04:00
a8294bb01a C2024-029 RO Editor - Referenced Object Definition Form - Add check if items changed before prompting to possibly save 2024-10-15 08:40:12 -04:00
28e4bdda29 Merge pull request 'B2024-079 Consistency of adding_editing_removing fields in RO Editor - Referenced Object Definition Form' (#430) from B2024-079 into Development
change are good.  Ready for testing phase.
2024-10-14 16:36:39 -04:00
7d408df904 B2024-079 Consistency of adding_editing_removing fields in RO Editor - Referenced Object Definition Form 2024-10-14 16:17:19 -04:00
caec6adf8d Merge pull request 'F2024-075 (Farley) Action verbs should be bolded no matter if title case or lower case - all formats' (#429) from F2024-075_FarlyRplWrds into Development
Format only change. OK to test.
2024-10-14 14:08:11 -04:00
a38c0dbe33 F2024-075 (Farley) Action verbs should be bolded no matter if title case or lower case - all formats 2024-10-14 14:06:17 -04:00
d779d4ad50 Merge pull request 'GIT_ATTRIBUTE_FILE - adjusting GIT settings so should be able to see diff of xml files in GIT (and not just Visual Studio' (#428) from GIT_ATRIBUTE_FILE into Development
No testing needed.  This is just a Git configuration setting for the developers.
2024-10-10 16:30:22 -04:00
9b71ce0fee GIT_ATTRIBUTE_FILE - adjusting GIT settings so should be able to see diff of xml files in GIT (and not just Visual Studio 2024-10-10 15:51:11 -04:00
8b18005b8e Merge pull request 'B2024-078 Bad Transition preventing editing of a substep. Can enter changed text, but then when move to another textbox, original text returns.' (#427) from B2024-078 into Development
changes good for testing phase.
2024-10-10 08:57:54 -04:00
a550ef1b50 B2024-078 Bad Transition preventing editing of a substep. Can enter changed text, but then when move to another textbox, original text returns. 2024-10-10 08:38:35 -04:00
63a60b32cc Merge pull request 'F2024-074 For Farley, Include the Cover Page in the total page count of the procedures' (#426) from F2024_074_FNP_CountCoverWithProcs into Development
format only change
2024-10-09 16:47:48 -04:00
ca4dc8d330 F2024-074 For Farley, Include the Cover Page in the total page count of the procedures 2024-10-09 16:45:38 -04:00
0a52aa5c53 Merge pull request 'C2024-024 Simple Selection of Fields to add to Return Values and Menu Values' (#423) from C2024-024 into Development
file changes look good - ready for testing phase.
2024-10-09 14:02:53 -04:00
591fc03ca2 C2024-024 Simple Selection of Fields to add to Return Values and Menu Values 2024-10-09 13:12:29 -04:00
ebd7b1249f Merge pull request 'C2024-023 Autocomplete on Group Definition Accessory Page Access Values.' (#422) from C2024-023 into Development
Ok for testing phase
2024-10-08 15:17:31 -04:00
1b6eeaf4ad C2024-023 Autocomplete on Group Definition Accessory Page Access Values. 2024-10-08 15:02:47 -04:00
1d3dac0e51 Merge pull request 'C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-5' (#421) from C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4 into Development
good for testing phase
2024-10-08 09:29:13 -04:00
48da58b681 C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-5 2024-10-08 08:54:32 -04:00
68639eadf0 Merge pull request 'C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4' (#420) from C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4 into Development
Looked Good. Ready for QA Testing.
2024-10-07 11:51:36 -04:00
dc77984c10 C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4 2024-10-07 11:40:26 -04:00
5b4e1cd694 C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4 2024-10-04 14:55:04 -04:00
3fbd974fa9 C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-4 2024-10-04 14:38:59 -04:00
b457496297 Merge pull request 'B2024-076 Correct Linking / Numbering when utilizing Paste Replace with Enhanced Steps over unlinked steps' (#419) from B2024-076 into Development
ready for testing phase
2024-10-04 13:20:09 -04:00
dd83491169 B2024-076 Correct Linking / Numbering when utilizing Paste Replace with Enhanced Steps over unlinked steps 2024-10-04 12:46:23 -04:00
a73a8fb993 Merge pull request 'C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-2' (#418) from C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-2 into Development
Code looked good. Ready for QA Testing.
2024-10-04 09:42:55 -04:00
fb7a99653d C2020-049-Add-the-ability-for-PROMS-to-remember-the-procedure-tabs-that-were-open-when-you-closed-PROMS-2 2024-10-03 15:11:15 -04:00
a34828113a Merge pull request 'Development' (#416) from Development into master
Merging C2017-031 and B2024-075 from development into master after successful testing.
2024-10-03 12:08:30 -04:00
297d75a2b3 Merge pull request 'B2024-075 Correct Linking and Numbering when utilizing Paste Before and Paste After with Enhanced Steps as well as some related UI refresh issues.' (#415) from B2024-075 into Development
Good for testing phase
2024-10-02 11:48:58 -04:00
47c5bb159a B2024-075 Correct Linking and Numbering when utilizing Paste Before and Paste After with Enhanced Steps as well as some related UI refresh issues. 2024-10-02 11:31:04 -04:00
610b2d178c Merge pull request 'C2017-031 Extend Copy / Paste Replace Functionality for Enhanced Background Steps' (#414) from C2017-031 into Development
Code changes look good. OK for testing phase.
2024-09-30 15:14:10 -04:00
bb45e551a3 C2017-031 Extend Copy / Paste Replace Functionality for Enhanced Background Steps 2024-09-30 15:02:35 -04:00
461329468c Merge pull request 'Development' (#413) from Development into master
Merging F2023-136 and F2024-074 in master after successful testing
2024-09-27 14:27:22 -04:00
77cf6177dc Merge pull request 'F2023-136 Adjust formats to not count the cover page when calculating the page numbers for the Automatic Table of Contents.' (#412) from F2023-136_Farley into Development
Format only  changes - ready for testing
2024-09-27 10:41:26 -04:00
a830856df2 F2023-136 Adjust formats to not count the cover page when calculating the page numbers for the Automatic Table of Contents. 2024-09-27 10:34:16 -04:00
efe215f4d0 Merge pull request 'B2024-074 When Deleting annotations via the Administrative Tools -> Delete -> Delete Annotations, and checking if a procedure is checked out prior to deletion:' (#411) from B2024-074 into Development
code changes look good. ready for testing phase
2024-09-24 11:04:40 -04:00
5e2e2f841c B2024-074 When Deleting annotations via the Administrative Tools -> Delete -> Delete Annotations, and checking if a procedure is checked out prior to deletion:
1. If no Number for Procedure, Display Title.
2. If only deleting annotations from an individual procedure, verify can check out procedure.
2024-09-24 10:47:44 -04:00
35de5df04d Merge pull request 'Development' (#410) from Development into master
Merging all items through B2024-03 from development into master after successful testing.
2024-09-17 12:03:23 -04:00
9da436ab2d Merge pull request 'B2024-070_072_Correct_Typos__Setpoint_ID__and__Category_of_Transitions' (#408) from B2024-070_072 into Development
Reviewed-on: #408
2024-09-16 15:05:15 -04:00
5333b96c88 Merge pull request 'B2024-073 Correct Object Reference Error that can occur in debug mode when utilizing Edit item from the Debug toolbar at the bottom of the application. Note - this bug is only in Debug Mode / Is not customer facing.' (#409) from B2024-073_DebugMode_EditItem_ActiveParent_ObjectReferenceError into Development
Reviewed-on: #409
2024-09-16 15:00:50 -04:00
6561a11661 B2024-073 Correct Object Reference Error that can occur in debug mode when utilizing Edit item from the Debug toolbar at the bottom of the application. Note - this bug is only in Debug Mode / Is not customer facing. 2024-09-16 13:10:52 -04:00
1c9334a52b B2024-070_072_Correct_Typos__Setpoint_ID__and__Category_of_Transitions 2024-09-16 11:53:20 -04:00
2e00693a33 Merge pull request 'B2024-068_069_check_if_current_annotation_is_not_selected_before_removal_of_annotation' (#407) from B2024-068_and_069 into Development
Ready for testing phase
2024-09-11 15:40:25 -04:00
8617ce4562 B2024-068_069_check_if_current_annotation_is_not_selected_before_removal_of_annotation 2024-09-11 15:34:22 -04:00
78416ef452 Merge pull request 'F2024-071, F2024-072, F2024-073 for Farley added Action Verbs bolding, sub-section attachment types, paginate attachmens with procedure' (#406) from FarleyFormatChanges into Development
format only change
2024-09-11 14:36:36 -04:00
9ad50af4dd F2024-071, F2024-072, F2024-073 for Farley added Action Verbs bolding, sub-section attachment types, paginate attachmens with procedure 2024-09-11 14:34:17 -04:00
a6f3d62a01 Merge pull request 'C2021-038-No-and_Cancel-button-2' (#405) from C2021-038-No-and_Cancel-button-2 into Development
ready for testing phase.
2024-09-11 10:47:39 -04:00
a25b5fc6b8 C2021-038-No-and_Cancel-button-2 2024-09-10 17:54:54 -04:00
9e26e94e97 Merge pull request 'C2021-040-Change-dialog-box-when-canceling-import-procedure' (#403) from C2021-040-Change-dialog-box-when-canceling-import-procedure into Development
ready for testing phase
2024-09-09 15:12:08 -04:00
a571cb5f15 C2021-040-Change-dialog-box-when-canceling-import-procedure 2024-09-09 14:58:03 -04:00
2e00c94d34 C2021-040-Change-dialog-box-when-canceling-import-procedure 2024-09-09 13:47:44 -04:00
4f0548fd60 Merge pull request 'Development' (#402) from Development into master
Merging C2021-034 and B2024-065 into master after successful testing.
2024-09-06 09:56:37 -04:00
f1506b9aee Merge pull request 'C2021-034-Change-applicability-dialog-box-response-from-Yes_No_Cancel-to-Yes_No' (#401) from C2021-034-Change-applicability-dialog-box-response-from-Yes_No_Cancel-to-Yes_No into Development
ready for testing phase
2024-09-06 08:37:45 -04:00
2805471301 C2021-034-Change-applicability-dialog-box-response-from-Yes_No_Cancel-to-Yes_No 2024-09-05 16:50:06 -04:00
89f55e091f Merge pull request 'B2024-065-Print-dialog-initalize-to-Working-Default-Level-Setting' (#400) from B2024-065-Print-dialog-initalize-to-Working-Default-Level-Setting into Development
ready for testing phase
2024-09-04 14:16:52 -04:00
da6c47d0ff B2024-065-Print-dialog-initalize-to-Working-Default-Level-Setting 2024-09-04 11:59:48 -04:00
5c1d96cc51 Merge pull request 'Development' (#399) from Development into master
Merging all fixes through B2024-063 from development into master after successful testing.
2024-08-27 15:58:15 -04:00
63cac73de3 Merge pull request 'B2024-063-Invalid-Format-message-box-displays-when-rev-date-empty-2' (#398) from B2024-063-Invalid-Format-message-box-displays-when-rev-date-empty-2 into Development
OK for testing phase
2024-08-27 11:08:30 -04:00
c8ed5b0565 B2024-063-Invalid-Format-message-box-displays-when-rev-date-empty-2 2024-08-27 11:04:23 -04:00
c6342fea49 Merge pull request 'B2024-060-Adding-a-picture-PROMS-crashes' (#396) from B2024-060-Adding-a-picture-PROMS-crashes into Development
Ok for testing phase
2024-08-27 10:33:56 -04:00
7a3748f7e0 B2024-060-Adding-a-picture-PROMS-crashes 2024-08-26 11:11:03 -04:00
516b479c0c B2024-060-Adding-a-picture-PROMS-crashes 2024-08-26 10:00:31 -04:00
a43e059733 Merge pull request 'F2024-070 - Add “DEVIATION:” to the enhanced background template after “KNOWLOEDGE/ABILITY”' (#395) from F2024-070_Catawba into Development
Format only change. ready for testing phase.
2024-08-22 11:26:17 -04:00
0ac79f4e46 F2024-070 - Add “DEVIATION:” to the enhanced background template after “KNOWLOEDGE/ABILITY” 2024-08-22 11:24:17 -04:00
c06744b3bb B2024-060-Adding-a-picture-PROMS-crashes 2024-08-22 08:19:20 -04:00
218a2c17a2 Merge pull request 'B2024-061- Added a null reference check in the save annotation code. Need for when Admin deletes the annotation while a user modified the text of it' (#394) from B2024-061 into Development
null reference check added to the code, tested locally before uploading
2024-08-21 11:45:10 -04:00
a629f6834b B2024-061- Added a null reference check in the save annotation code. Need for when Admin deletes the annotation while a user modified the text of it 2024-08-21 11:37:37 -04:00
bf5337cf63 B2024-062 printing a procedure that is empty displays the Empty Procedure message. WhenOK button is clicked, PROMS will exit the Print function.. (#393)
B2024-062
When you attempt to print a procedure that is empty (i.e. none of the sections are applicable to the selected Child to print), the Empty Procedure message appears. When you click the OK button PROMS will now simply exit the Print function instead of displaying the “Try Again” message box.

Reviewed-on: #393
Reviewed-by: Paul Larsen <plarsen@volian.com>
Co-authored-by: John Jenko <jjenko@volian.com>
Co-committed-by: John Jenko <jjenko@volian.com>
2024-08-20 12:25:42 -04:00
57049c0c52 Merge pull request 'Development' (#392) from Development into master
Merging B2024-059 and B2024-058 from development into master after successful testing.
2024-08-15 14:55:27 -04:00
7713f0cd63 Merge pull request 'B2024-059: Paste source section has bad links.' (#391) from B2024-059 into Development
Reviewed-on: #391
Reviewed-by: Paul Larsen <plarsen@volian.com>
2024-08-15 10:10:13 -04:00
2711520666 B2024-059: Paste source section has bad links. 2024-08-15 06:51:02 -04:00
4a6c0ba447 Merge pull request 'B2024-058-RevisionDate-field-Print-dialog' (#390) from B2024-058-RevisionDate-field-Print-dialog into Development
Reviewed-on: #390
Reviewed-by: Kathy Ruffing <kruffing@volian.com>
2024-08-14 12:04:36 -04:00
3f3281e2f4 B2024-058-RevisionDate-field-Print-dialog 2024-08-14 09:37:26 -04:00
0eadd3fe33 B2024-058-RevisionDate-field-Print-dialog 2024-08-13 14:01:38 -04:00
4bf42be80a B2024-058-RevisionDate-field-Print-dialog 2024-08-13 10:05:05 -04:00
31326e1c91 Merge pull request 'Development' (#389) from Development into master
Merging all changes through F2024-069 from development into master after successful testing.
2024-08-09 13:06:40 -04:00
d7f829737a B2024-058-RevisionDate-field-Print-dialog 2024-08-08 15:21:11 -04:00
25cc62c7c6 Merge pull request 'F2024-069-Procedure-Set-Specific-Information-dialog-ajustments' (#388) from F2024-069-Procedure-Set-Specific-Information-dialog-ajustments into Development
changes good. ready for testing
2024-08-08 14:13:28 -04:00
47596c7bca Merge pull request 'F2024-067 - Updates to VCSummer for time sensitive stes (clock)' (#387) from F2024-067 into Development
format change ready for testing
2024-08-08 14:12:05 -04:00
7129853902 F2024-069-Procedure-Set-Specific-Information-dialog-ajustments 2024-08-08 13:33:16 -04:00
f08466f702 Merge pull request 'B2024-038: tree view menuing for paste/replace of sections' (#386) from B2024-038 into Development
Reviewed-on: #386
Reviewed-by: Kevin Laskey <klaskey@volian.com>
2024-08-08 10:18:27 -04:00
4248d40917 B2024-058-RevisionDate-field-Print-dialog 2024-08-08 09:27:27 -04:00
7cf28366f4 B2024-038: tree view menuing for paste/replace of sections 2024-08-08 09:01:31 -04:00
037c82e22e Merge pull request 'F2024-068-VCS-Deviation-Format' (#385) from F2024-068-VCS-Deviation-Format into Development
ok for testing phase
2024-08-08 08:29:10 -04:00
6de13b12f9 F2024-068-VCS-Deviation-Format 2024-08-07 21:59:59 -04:00
cf69aa93e6 Merge pull request 'B2024-057 - Updated sizes of tooltips in delete area of admin' (#384) from B2024-057 into Development
OK for testing
2024-08-07 15:22:41 -04:00
4b915b78b6 B2024-057 - Updated sizes of tooltips in delete area of admin 2024-08-07 14:37:31 -04:00
a891a62ffa F2024-067 - Updates to VCSummer for time sensitive stes (clock) 2024-08-07 14:15:57 -04:00
7a768484a1 Merge pull request 'B2024-057' (#382) from B2024-057 into Development
approved, ready for testing
2024-08-06 11:18:30 -04:00
5f7af3309d B2024-054 - Update Annotation tooltip 2024-08-06 11:17:17 -04:00
1f3a1dabbc B2024-055 - Update tooltips for the labels on delete annotations and delete folders 2024-08-06 10:58:04 -04:00
4b61495960 B2024-057 - updated curors 2024-08-06 10:48:05 -04:00
d091a37171 B2024-055 - Update tooltips on admin delete functions 2024-08-06 10:29:06 -04:00
189b78d7d3 B2024-057 - Added check to see if anything is checked out for annotations and folder delete from admin area. 2024-08-06 09:14:36 -04:00
8ee7a31b97 Merge pull request 'C2024-018 - Update to use results pane' (#381) from C2024-018 into Development
approved and ready for testing phase
2024-08-05 15:29:46 -04:00
055be66421 C2024-018 - Update to use results pane 2024-08-05 15:24:43 -04:00
86a3e56a27 Merge pull request 'C2024-018 - Updated fixes per Michelle testing. Added some confirmation messages' (#380) from C2024-018 into Development
changes approved. - ready for testing phase
2024-08-05 12:12:05 -04:00
0db98e4182 C2024-018 - Updated fixes per Michelle testing. Added some confirmation messages 2024-08-05 11:12:21 -04:00
3102596a3d Merge pull request 'C2021-059_deleteFolders' (#379) from C2021-059_deleteFolders into Development
code changes look good.  - on to testing phase
2024-08-02 14:05:24 -04:00
41aa195785 C2021-059 - Added extra code to ensure delect sets parent tree items deslected 2024-08-02 13:08:19 -04:00
954186265e C2021-059 - Patch in auto checkbox filling for delete tree. 2024-08-02 12:56:12 -04:00
33cced07c6 C2021-059 Added veProms connection to remove the node in the main tree 2024-08-02 10:31:50 -04:00
afbf6f360d C2021-059 - Updates to get build moving after custom merging 2024-08-02 10:13:05 -04:00
df2be585a1 C2021-059 - Moved updates to branch 2024-08-01 15:54:28 -04:00
c81f527cb8 C2021-059 - Update Proms Fixes 2024-08-01 15:05:42 -04:00
0f67382c27 Merge pull request 'B2024-054_Update_Tool_tip_text_for_delete_annotations' (#375) from B2024-054_Update_Tool_tip_text_for_delete_annotations into Development
changes look good - onto testing phase
2024-08-01 11:07:59 -04:00
b42b8ddfa3 B2024-054_Update_Tool_tip_text_for_delete_annotations 2024-08-01 10:42:53 -04:00
3c60994a0a Merge pull request 'Development' (#373) from Development into master
Merging all changes through B2024-053 from development into master after successful testing.
2024-08-01 08:37:23 -04:00
f3efd409c6 Merge pull request 'B2024-053_Submitted_for_Admin_Tools-Delete' (#372) from B2024-053_Submitted_for_Admin_Tools-Delete into Development
passed code review - on to testing phase.
2024-07-31 14:41:13 -04:00
9011b134d6 B2024-053_Submitted_for_Admin_Tools-Delete 2024-07-31 14:34:49 -04:00
7c33bad362 Merge pull request 'B2024-052-In-Annotations-pop-up-no-Annotation-type-should-be-selected-by-default' (#371) from B2024-052-In-Annotations-pop-up-no-Annotation-type-should-be-selected-by-default into Development
changes look good - onto testing phase
2024-07-31 09:49:30 -04:00
e49a4d674f Merge pull request 'B2024-045, B2024-049, B2024-050 crash on paste/replace' (#370) from B2024-045 into Development
Reviewed-on: #370
Reviewed-by: Kevin Laskey <klaskey@volian.com>
2024-07-31 09:48:50 -04:00
7872f192ed B2024-052-In-Annotations-pop-up-no-Annotation-type-should-be-selected-by-default 2024-07-31 09:23:34 -04:00
870bba0aa6 B2024-045, B2024-049, B2024-050 crash on paste/replace 2024-07-31 07:21:30 -04:00
35c7b2b0cf Merge pull request 'B2024-051 Added null checks in the MultiUser.cs file to handle when a user as access to a procedure set that no longer exists.' (#369) from B2024-051 into Development
Reviewed-on: #369
2024-07-30 15:46:21 -04:00
9e6c8acca4 B2024-051 Added null checks in the MultiUser.cs file to handle when a user as access to a procedure set that no longer exists. 2024-07-30 14:48:34 -04:00
099bbdd328 Merge pull request 'B2024-043-Fix-User-Tab2' (#368) from B2024-043-Fix-User-Tab2 into Development
changes look good. onto the testing phase
2024-07-30 10:38:31 -04:00
720c5db2d0 B2024-043-Fix-User-Tab2 2024-07-30 10:09:40 -04:00
659833c5bf Merge pull request 'C2024-016-Annotations-Delete-Info-to-results-panel' (#366) from C2024-016-Annotations-Delete-Info-to-results-panel into Development
changes OK. ready to create test exe.
2024-07-29 14:12:10 -04:00
5ea9bcdd8b C2024-016-Annotations-Delete-Info-to-results-panel 2024-07-29 12:52:29 -04:00
3ec7c11797 Merge pull request 'C2024-017 Removed old (not implemented) format variables and settings from the format files and removed incomplete references to them in the C# code. Also added descriptions of the used format variables in the C# code that hooks the XML format files t…' (#364) from C2024-017_RemoveUnUsedFormatItems into Development
format cleanup. any code changes were to add comments (description of format variables) and to remove commented out and un-used code.
2024-07-26 14:57:56 -04:00
7f899175d1 C2024-017 Removed old (not implemented) format variables and settings from the format files and removed incomplete references to them in the C# code. Also added descriptions of the used format variables in the C# code that hooks the XML format files to the PROMS C# logic. 2024-07-26 14:54:11 -04:00
112edd1c8a Merge pull request 'B2024-048-Annotations-Cleanup-tools-tips' (#363) from B2024-048-Annotations-Cleanup-tools-tips into Development
changes are good. ready for testing phase
2024-07-26 10:57:20 -04:00
819c1bbec4 B2024-048-Annotations-Cleanup-tools-tips 2024-07-26 09:38:25 -04:00
773cc42346 Merge pull request 'Development' (#362) from Development into master
Merging B2024-046 and B2024-047 from development into master after successful testing.
2024-07-25 10:44:42 -04:00
6b6968561b B2024-048-Annotations-Cleanup-tools-tips 2024-07-25 08:13:20 -04:00
24fbb69e25 Merge pull request 'B2024-047-Fix-Size-Treeview-In-Link-Tab-Admin-Tools' (#361) from B2024-047-Fix-Size-Treeview-In-Link-Tab-Admin-Tools into Development
ready for testing phase
2024-07-24 16:28:04 -04:00
79751732a3 B2024-047-Fix-Size-Treeview-In-Link-Tab-Admin-Tools 2024-07-24 16:11:52 -04:00
e6e62ed2c8 Merge pull request 'B2024-046-Set-Default-Tab-In-Admin-Tools' (#360) from B2024-046-Set-Default-Tab-In-Admin-Tools into Development
change looks good to continue with testing phase.
2024-07-24 10:44:56 -04:00
8f2cbf4081 B2024-046-Set-Default-Tab-In-Admin-Tools 2024-07-24 10:37:59 -04:00
f46a1f39dc Merge pull request 'Development' (#359) from Development into master
Merging B2024-042 from development into master after successful testing.
2024-07-22 11:14:19 -04:00
c25f501909 Merge pull request 'B2024-042 - When replacing a procedure, this change will now replace the procedure correctly and add it to the tree node, previously it would replace th eprocedure, then add a whole new procedure to the node, incorrectly using the copy procedure which …' (#358) from B2024-042 into Development
Reviewed-on: #358
Reviewed-by: Kathy Ruffing <kruffing@volian.com>
2024-07-22 09:45:17 -04:00
bf72a6bf78 B2024-042 - Update TreeNodeReplace section when adding a node to working draft (remove unneeded code) 2024-07-22 09:39:13 -04:00
b7175bf77f Merge pull request 'Development' (#357) from Development into master
Merging C2024-005 from development into master after successful testing.
2024-07-18 15:41:20 -04:00
a1380dbb8a B2024-042 - When replacing a procedure, this change will now replace the procedure correctly and add it to the tree node, previously it would replace th eprocedure, then add a whole new procedure to the node, incorrectly using the copy procedure which appended "copy of". 2024-07-18 14:06:01 -04:00
501798a8cb Merge pull request 'C2024-005-Annotations-Cleanup-2' (#355) from C2024-005-Annototions-Cleanup-2 into Development
Reviewed-on: #355
Reviewed-by: Kathy Ruffing <kruffing@volian.com>
Code reviewed successfully
2024-07-18 11:39:12 -04:00
a240bc2c19 C2024-005-Annotations-Cleanup-2 2024-07-18 11:31:49 -04:00
a804a3866a C2024-005-Annotations-Cleanup-2 2024-07-18 11:12:30 -04:00
ec22232aa8 Merge pull request 'Development' (#356) from Development into master
Merging all items through B2024-041 from development into master after successful testing.
2024-07-18 09:51:54 -04:00
069ffb80e9 C2024-005-Annotations-Cleanup-2 2024-07-17 14:28:24 -04:00
5255080291 Merge pull request 'B2022-118: search of multi value ROs fails' (#354) from B2022-118 into Development
Reviewed-on: #354
2024-07-17 10:56:40 -04:00
ae35d9f0d7 B2022-118: search of multi value ROs fails 2024-07-17 10:11:43 -04:00
afbd653611 Merge pull request 'B2024-041 - Update PromsFixes SQL file to acocunt for replacing vs pasting procs' (#352) from B2024-041_v2 into Development
good for testing phase
2024-07-16 16:27:35 -04:00
9a55111e1e B2024-041 - Update PromsFixes SQL file to acocunt for replacing vs pasting procs 2024-07-16 16:20:21 -04:00
422a3053b7 Merge pull request 'B2024-039 Customer reported that transitions to standard text get converted to text when the Refresh Transitions is done from the Admin Tools' (#350) from B2024-039_BNPP_StdtxtTrans into Development
format only changes
2024-07-12 14:16:22 -04:00
feb74ee09f B2024-039 Customer reported that transitions to standard text get converted to text when the Refresh Transitions is done from the Admin Tools 2024-07-12 14:14:23 -04:00
7cebb2b7f1 Merge pull request 'B2024-037: Bug fix for copy/replace functionality on procedures and steps.' (#349) from B2024-037 into Development
changes look good. OK for testing phase.
2024-07-11 10:54:10 -04:00
8097c6283c B2024-037 - Update versioning on proms fixes 2024-07-11 10:30:31 -04:00
8f08ef5ee4 B2024-037 - Slight clean up on parentedititme 2024-07-11 08:45:18 -04:00
fd26f16776 B2024-037 Include proms sql fixes for copy replace functionality 2024-07-10 14:53:20 -04:00
21a83df99d B2024-037 - Fixes made for replacing procs and steps via paste/replace functionality. 2024-07-10 12:15:14 -04:00
f303cd2236 Merge pull request 'Development' (#348) from Development into master
Merging F2024-065 and F2024-066 from development into master after successful testing.
2024-07-03 10:45:41 -04:00
616acf0e37 Merge pull request 'F2024-065 - Turned off the CapRoIfLastLower flag in all of the Beaver Valley formats F2024-066 - Turned off the Replace Words feature in EOP, “without Issue Number”, and the SAMG Background formats' (#347) from F2024-065-066-BeaverValley into Development
Format only changes
2024-07-03 10:08:45 -04:00
3cff87cf97 F2024-065 - Turned off the CapRoIfLastLower flag in all of the Beaver Valley formats F2024-066 - Turned off the Replace Words feature in EOP, “without Issue Number”, and the SAMG Background formats 2024-07-03 10:01:03 -04:00
f40cef4416 Merge pull request 'Development' (#346) from Development into master
Merging F2024-064 from development into master after successful testing.
2024-07-01 11:54:15 -04:00
9202d903a5 Merge pull request 'F2024-064: underline and spacing of section titles' (#345) from F2024-064 into Development
Reviewed-on: #345
2024-07-01 09:27:34 -04:00
a9a9a56c09 F2024-064: underline and spacing of section titles 2024-07-01 09:15:42 -04:00
fbca97d38d Merge pull request 'Development' (#344) from Development into master
Merging C2024-013 from development into master after successful testing.
2024-06-25 15:55:32 -04:00
aee7819a9c Merge pull request 'C2024-013: On print dialog, disable Merge button if creating hyperlinks' (#343) from C2024-013 into Development
code changed reviewed and can proceed to testing phase
2024-06-25 13:42:33 -04:00
d3bc1c4725 C2024-013: On print dialog, disable Merge button if creating hyperlinks 2024-06-25 12:14:26 -04:00
28bd2cba5c Merge pull request 'Development' (#342) from Development into master
Merging C2022-029 from development into master after successful testing.
2024-06-20 11:36:59 -04:00
4b35f73bbf Merge pull request 'Development' (#340) from Development into master
Merging C2024-004 from development into master after successful testing.
2024-06-19 16:23:23 -04:00
f4706eb126 Merge pull request 'Development' (#338) from Development into master
Merging C2019-047 from development into master after successful testing.
2024-06-17 08:38:34 -04:00
21bcb90558 Merge pull request 'Development' (#335) from Development into master
Merging B2024-036 and F2024-063 from development into master after successful testing.
2024-06-06 14:51:13 -04:00
ae48ac0cae Merge pull request 'Development' (#332) from Development into master
Merging changes through B2024-035 from development into master after successful testing.
2024-05-30 08:08:28 -04:00
cb4979d5bc Merge pull request 'Development' (#327) from Development into master
Merging F2024-061 from development into master after successful testing.
2024-05-20 14:11:12 -04:00
7d3ae74e1f Merge pull request 'Development' (#325) from Development into master
Merging F2024-060 from development into master after successful testing.
2024-05-16 15:32:13 -04:00
9d680aa500 Merge pull request 'Development' (#323) from Development into master
Merging C2024-001 from development into master after successful testing.
2024-05-16 14:17:17 -04:00
0d50b1c2fe Merge pull request 'Development' (#321) from Development into master
Merging all items through B2024-030 from development into master after successful testing.
2024-05-15 08:33:58 -04:00
75e034863f Merge pull request 'Development' (#315) from Development into master
Merging all changes through B2024-026 from development into master after successful testing.
2024-05-09 14:01:48 -04:00
3b42de1571 Merge pull request 'F2024-059_Callaway' (#311) from F2024-059_Callaway into master
Format only changes
2024-05-07 16:00:36 -04:00
668472286e Merge pull request 'Development' (#307) from Development into master
Merging all changes through C2023-006 into master after successful testing.
2024-04-26 09:21:44 -04:00
e00d34c99d Merge pull request 'Development' (#300) from Development into master
Merging C2024-008 and C2024-007 from development into master after successful testing.
2024-04-17 14:57:22 -04:00
9fb496dfb3 Merge pull request 'Development' (#297) from Development into master
Merging F2024-053 from development into master after successful testing.
2024-04-11 09:23:34 -04:00
f4eaa4a3ef Merge pull request 'Development' (#295) from Development into master
Merging F2024-052 from development into master after successful testing.
2024-04-08 11:11:43 -04:00
5d50ed6bdf Merge pull request 'Development' (#292) from Development into master
Merging F2024-051, B2024-021, F2024-049, F2024-050 and F2024-045 after successful testing.
2024-04-05 10:54:57 -04:00
d7ace4eaf9 Merge pull request 'Development' (#287) from Development into master
Merging F2024-047, F2024-048, B2024-017 and B2024-019 from development into master after successful testing.
2024-04-04 11:36:56 -04:00
16a4d335ea Merge pull request 'Development' (#282) from Development into master
Merging all items through B2024-018 from development into master after successful testing.
2024-03-27 13:39:46 -04:00
ba69bb0772 Merge pull request 'Development' (#275) from Development into master
Merging F2024-037 and CSLA updates into master after successful testing.
2024-03-20 16:07:27 -04:00
455940caa2 Merge pull request 'Development' (#271) from Development into master
Merging F2024-040 into master after successful testing.
2024-03-18 10:00:30 -04:00
439344757e Merge pull request 'Development' (#269) from Development into master
Merging F2024-044, F2024-043, and F2024-019 in master after successful testing.
2024-03-15 09:33:57 -04:00
ad912691c9 Merge pull request 'Development' (#265) from Development into master
Merging 	F2024-016, 	F2024-032, 	B2024-013, 	F2024-025,	F2024-027 & F2024-028 into master after successful testing.
2024-03-12 14:01:12 -04:00
237144aff6 Merge pull request 'Development' (#259) from Development into master
Merging B2024-014 from development into master after successful testing.
2024-03-04 15:02:18 -05:00
810332d558 Merge pull request 'Development' (#256) from Development into master
Merging F2024-020 from development into master.  No testing required since formats are under development.
2024-02-29 13:23:48 -05:00
f8431d0ba1 Merge pull request 'Development' (#252) from Development into master
Merging F2024-022 from development into master.  No testing required since formats are under development.
2024-02-29 09:23:51 -05:00
57c3bfa16a Merge pull request 'Development' (#250) from Development into master
Merging C2023-003 and F2024-026 into master after successful testing.
2024-02-28 11:56:15 -05:00
61f1077608 Merge pull request 'Development' (#248) from Development into master
Merging F2024-029, B2024-009, F2024-023, B2024-011, B2024-012 and F2024-017 from development into master after successful testing.
2024-02-27 14:21:22 -05:00
8877e968b9 Merge pull request 'Development' (#239) from Development into master
Merging F2024-018, B2024-008, B2024-007, and F2024-015 from development into master after successful testing.
2024-02-22 08:22:26 -05:00
4575c90bee Merge pull request 'Development' (#233) from Development into master
Merging updated formats from development into master after successful testing.
2024-02-14 16:07:57 -05:00
21279a87ae Merge pull request 'Development' (#231) from Development into master
Merging B2024-006 from development into master after successful testing.
2024-02-14 08:19:09 -05:00
3d5ad4a17e Merge pull request 'Development' (#229) from Development into master
Merging C2024-002 and F2024-013 from development into master after successful testing.
2024-02-09 11:30:41 -05:00
9bb7b044a8 Merge pull request 'Development' (#226) from Development into master
Merging F2024-010, 	F2024-011, 	F2024-008, 	B2024-002, 	F2024-012  and B2024-005 from development into master after successful testing.
2024-02-08 11:38:49 -05:00
dc8f2f7561 Merge pull request 'Development' (#219) from Development into master
Merging C2022-009 into master after successful testing.
2024-02-02 13:53:22 -05:00
829dbf84da Merge pull request 'Development' (#217) from Development into master
Merging F2024-005 and B2024-004 from development into master after successful testing
2024-01-31 08:34:00 -05:00
7b156c17f8 Merge pull request 'Development' (#212) from Development into master
Merging all changes up through F2024-006 from development into master after successful testing.
2024-01-24 11:30:40 -05:00
cbf7cbc164 Merge pull request 'Development' (#198) from Development into master
Merging F2024-002 and F2023-112 from development into master.  No testing required since formats are under development.
2024-01-08 15:24:15 -05:00
b04faa816e Merge pull request 'Development' (#196) from Development into master
Merging F2023-126, F2024-001, C2022-009, C2023-024 and C2023-023 from development into Master after successful testing.
2024-01-03 10:54:22 -05:00
517ebe2902 Merge pull request 'Development' (#189) from Development into master
Initial check-in of Vogtle Background formats.  No testing required since formats are under development.
2023-12-15 15:48:55 -05:00
03d0d314e3 Merge pull request 'Development' (#187) from Development into master
Merging B2023-115 from development into master after successful testing.
2023-12-12 15:31:06 -05:00
3e804c5cce Merge pull request 'Development' (#185) from Development into master
Merging F2023-133 into from development into master. No testing required since formats are under development.
2023-12-11 10:08:22 -05:00
ee2b8b538e Merge pull request 'Development' (#183) from Development into master
Merging PROMSFixes from development into master after minor changes to UpdateFormatList.
2023-12-08 14:51:21 -05:00
fdfd34fe92 Merge pull request 'Development' (#181) from Development into master
Merging F2023-151 from development into master.  No testing required since formats are under development.
2023-12-07 15:55:16 -05:00
2d6fb6523b Merge pull request 'Development' (#179) from Development into master
Merging F2023-133 from development into master.  No testing required since formats are under development.
2023-12-07 11:44:31 -05:00
3084bf3982 Merge pull request 'Development' (#177) from Development into master
Merging B2023-115 and F2023-150 from development into master.  No testing required since formats are under development.
2023-12-06 09:08:18 -05:00
5ba51e8392 Merge pull request 'Development' (#174) from Development into master
Merging F2023-149 from development into master.  No testing required since formats are under development.
2023-12-05 16:30:39 -05:00
fb5eb43e34 Merge pull request 'Development' (#172) from Development into master
Merging F2023-124 from development into master.  No testing required since formats are under development.
2023-12-04 11:22:59 -05:00
b154056276 Merge pull request 'Development' (#170) from Development into master
Merging F2023-119 from development into master.  No testing required since formats are under development.
2023-12-01 15:36:22 -05:00
c67b8f9ca1 Merge pull request 'Development' (#168) from Development into master
Merging F2023-146 from development to master.  No testing required since formats are under development.
2023-12-01 10:02:50 -05:00
95e4181360 Merge pull request 'Development' (#166) from Development into master
Merging F2023-148, F2023-148, and B2023-120 from development into Master. No testing required since formats are under development.
2023-11-30 14:38:49 -05:00
32dffbe56b Merge pull request 'Development' (#162) from Development into master
Merging B2023-116, B2023-117, and F2023-143 from development to master after successful testing.
2023-11-29 15:58:44 -05:00
6b3c8d373b Merge pull request 'F2023-143_Vogtle3&4_Alrm_Footer' (#159) from F2023-143_Vogtle3&4_Alrm_Footer into master
Format only change.
Vogtle 3&4 formats under development. This change will be tested as data in entered into PROMS by Volian
2023-11-27 16:23:44 -05:00
db29107f47 Merge pull request 'Development' (#156) from Development into master
Merging F2023-142 and B2022-046 in from development to master after successful testing.
2023-11-14 08:45:47 -05:00
355537f2ab Merge pull request 'Development' (#153) from Development into master
Merging F2023-140, F2023-123, B2023-007, B2023-108, F2023-139, F2023-138 and B2023-103
2023-11-09 10:33:40 -05:00
0729ef0c21 Merge pull request 'Development' (#147) from Development into master
Merging F2023-139 from development into master after successful testing.
2023-10-26 10:10:33 -04:00
6fe82bfd0f Merge pull request 'Development' (#145) from Development into master
Merging F2023-138 from development into master after successful testing.
2023-10-25 14:40:15 -04:00
39bf072363 Merge pull request 'Development' (#142) from Development into master
Merging B2023-103 from development into master after successful testing.
2023-10-23 15:28:31 -04:00
da7c384fd8 Merge pull request 'Development' (#139) from Development into master
Merging C2023-017, C2023-019, B2023-104, B2023-101 and B2023-102 from development into master after successful testing.
2023-10-18 10:37:59 -04:00
95130fd9a0 Merge pull request 'Development' (#133) from Development into master
Merging C2023-018 from development into master after successful testing.
2023-10-11 09:26:45 -04:00
978e2344a3 Merge pull request 'Development' (#131) from Development into master
Merging C2023-016 and C2023-017 from development into master after successful testing.
2023-10-06 10:56:34 -04:00
c9bf45602c Merge pull request 'Development' (#128) from Development into master
Merging F2023-137 and B2023-100 from development into master. F2023-137 does not require testing since formats are under development. B2023-100 tested successfully.
2023-10-02 11:52:22 -04:00
aa160b2036 Merge pull request 'Development' (#124) from Development into master
Merging B2023-099 from development into master after successful testing.
2023-09-28 15:58:27 -04:00
f82b32d351 Merge pull request 'Development' (#122) from Development into master
Merging B2023-097 and B2023-098 from development into master after successful testing.
2023-09-26 14:58:05 -04:00
e519dc9a57 Merge pull request 'Development' (#120) from Development into master
Merging B2023-094 from development into master after successful testing.
2023-09-22 13:24:17 -04:00
f020c37db9 Merge pull request 'Development' (#118) from Development into master
Merged B2023-096 from development into master after successful testing.
2023-09-15 11:50:57 -04:00
5a4ec3b6b1 Merge pull request 'Development' (#117) from Development into master
Merging F2023-135 and B2023-093 from development into master after successful testing.
2023-09-14 15:58:52 -04:00
2602d6c9d2 Merge pull request 'Development' (#113) from Development into master
Merging C2023-015 from development into master.
2023-09-12 09:23:57 -04:00
ff403583d7 Merge pull request 'Development' (#111) from Development into master
Merging B2023-091 and B2023-078 from development into master.
2023-08-30 16:07:17 -04:00
c5577cc2bd Merge pull request 'Development' (#108) from Development into master
Merging F2023-134 from development into master.  No testing required since formats are under development.
2023-08-24 15:01:12 -04:00
78be6e5dc1 Merge pull request 'Development' (#106) from Development into master
Merging GitAutomation from Development into Master.
2023-08-24 09:13:06 -04:00
b954a41375 Merge pull request 'Development' (#104) from Development into master
Merging B2023-089 and F2023-131 from Development into Master.  No testing required since formats are under development.
2023-08-24 09:05:31 -04:00
0100a11cfe Merge pull request 'Development' (#101) from Development into master
Merging F2023-125 from development into master.  No testing required since formats are under development.
2023-08-23 08:19:00 -04:00
04cf2e8534 Merge pull request 'Development' (#99) from Development into master
Merging F2023-130 from Development into Master. No testing required since formats are under development.
2023-08-22 15:04:22 -04:00
be00724818 Merge pull request 'Development' (#97) from Development into master
Merging B2023-088 from development into master.  No testing required since formats are under development.
2023-08-22 10:52:09 -04:00
274d93c61a Merge pull request 'Development' (#94) from Development into master
Merging F2023-122 from development into master.  No testing required since formats are under development.
2023-08-22 08:53:57 -04:00
7dc4c30436 Merge pull request 'Development' (#92) from Development into master
Merging F2023-127 from development into master.  No testing required since formats are under development.
2023-08-22 08:33:56 -04:00
028ef4bc31 Merge pull request 'Development' (#89) from Development into master
Merging F2023-128 and F2023-129 from development into master.  No testing required since formats are under development.
2023-08-21 11:46:01 -04:00
42124d65c7 Merge pull request 'Development' (#87) from Development into master
Merging F2023-118,  F2023-120 and F2023-121 from development into master.  No testing required since formats are under development.
2023-08-16 10:13:52 -04:00
3269 changed files with 1163668 additions and 171805 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,211 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
///<summary>
/// A strongly-typed collection of <see cref="Cell"/> objects.
///</summary>
public class CellCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the class.</summary>
public CellCollection()
{
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="cell">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(Cell cell)
{
return List.Add(cell);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Cell this[int index]
{
get {return (Cell)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Returns reference to the object in collection based on it's name. Returns null/nothing if cell with given name is not found.
/// </summary>
public Cell this[string name]
{
get
{
foreach (Cell item in List)
{
if (item.Name == name) return item;
}
return null;
}
}
/// <summary>
/// Gets the cell based on the column name. Node must be able to reach AdvTree control for this method to work.
/// </summary>
/// <param name="columnName">Column name.</param>
/// <returns>Cell object or null.</returns>
public Cell GetByColumnName(string columnName)
{
if (string.IsNullOrEmpty(columnName))
throw new ArgumentException("columnName argument must be non-empty non-null string with column name");
Node parentNode = this.ParentNode;
AdvTree tree = parentNode.TreeControl;
if (tree == null)
throw new NullReferenceException("AdvTree control cannot be reached. Node is not added to a tree.");
Cell cell = null;
if (parentNode.Parent != null && parentNode.Parent.NodesColumns.Count > 0)
{
int index= parentNode.Parent.NodesColumns.IndexOf(columnName);
if (index >= 0) cell = this[index];
}
else
{
int index = tree.Columns.IndexOf(columnName);
if (index >= 0) cell = this[index];
}
return cell;
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, Cell value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Cell value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Cell value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(Cell value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
Cell cell=value as Cell;
cell.SetParent(null);
if(m_ParentNode!=null)
m_ParentNode.OnCellRemoved(cell);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
Cell cell=value as Cell;
if(cell.Parent!=null && cell.Parent!=m_ParentNode)
cell.Parent.Cells.Remove(cell);
cell.SetParent(m_ParentNode);
if(m_ParentNode!=null)
m_ParentNode.OnCellInserted(cell);
}
protected override void OnInsert(int index, object value)
{
if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count > 0)
{
Cell cell = value as Cell;
if (cell.Site == null && this.List.Contains(cell)) this.List.Remove(cell);
}
base.OnInsert(index, value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Cell[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Cell array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(Cell[] array)
{
List.CopyTo(array,0);
}
private Cell _RootCell = null;
protected override void OnClear()
{
if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count>0)
{
if (this[0].Site == null)
_RootCell = this[0];
}
base.OnClear();
}
protected override void OnClearComplete()
{
base.OnClearComplete();
if (_RootCell != null)
{
this.Add(_RootCell);
_RootCell = null;
}
}
protected override void OnSet(int index, object oldValue, object newValue)
{
base.OnSet(index, oldValue, newValue);
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Cell that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
#endregion
}
}

View File

@ -0,0 +1,105 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents event arguments for cell editing events.
/// </summary>
public class CellEditEventArgs : EventArgs
{
/// <summary>
/// Indicates the action that caused the event.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the cell that is affected.
/// </summary>
public DevComponents.AdvTree.Cell Cell=null;
/// <summary>
/// Indicates new text that will be assigned to the cell if one is appropriate for given event.
/// </summary>
public string NewText="";
private ICellEditControl _Editor = null;
/// <summary>
/// Gets reference to the cell editor control.
/// </summary>
public ICellEditControl Editor
{
get
{
return _Editor;
}
}
/// <summary>
/// Indicates whether the current action is cancelled. For BeforeCellEdit event setting this
/// property to true will cancel the editing. For AfterCellEdit event setting this property to
/// true will cancel any changes made to the text and edits will not be accepted. For CellEditEnding
/// event setting this property to true will keep the cell in edit mode.
/// </summary>
public bool Cancel=false;
/// <summary>
/// Indicates whether editing operation was canceled by the end user, usually by pressing ESCAPE key.
/// </summary>
public readonly bool IsUserCanceled;
/// <summary>
/// Initializes new instance of CellEditEventArgs class.
/// </summary>
/// <param name="cell">Reference to Cell this event is raised for.</param>
/// <param name="action">Indicates the action that caused the event.</param>
/// <param name="newText">Indicates new text of the cell if it applies to given event.</param>
public CellEditEventArgs(Cell cell, eTreeAction action, string newText)
{
this.Action=action;
this.Cell=cell;
this.NewText=newText;
this.IsUserCanceled = false;
}
/// <summary>
/// Initializes new instance of CellEditEventArgs class.
/// </summary>
/// <param name="cell">Reference to Cell this event is raised for.</param>
/// <param name="action">Indicates the action that caused the event.</param>
/// <param name="newText">Indicates new text of the cell if it applies to given event.</param>
public CellEditEventArgs(Cell cell, eTreeAction action, string newText, ICellEditControl editor)
{
this.Action = action;
this.Cell = cell;
this.NewText = newText;
this.IsUserCanceled = false;
_Editor = editor;
}
/// <summary>
/// Initializes new instance of CellEditEventArgs class.
/// </summary>
/// <param name="cell">Reference to Cell this event is raised for.</param>
/// <param name="action">Indicates the action that caused the event.</param>
/// <param name="newText">Indicates new text of the cell if it applies to given event.</param>
/// <param name="isUserCanceled">Indicates whether action is canceled by the end user.</param>
public CellEditEventArgs(Cell cell, eTreeAction action, string newText, bool isUserCanceled)
{
this.Action = action;
this.Cell = cell;
this.NewText = newText;
this.IsUserCanceled = isUserCanceled;
}
/// <summary>
/// Initializes new instance of CellEditEventArgs class.
/// </summary>
/// <param name="cell">Reference to Cell this event is raised for.</param>
/// <param name="action">Indicates the action that caused the event.</param>
/// <param name="newText">Indicates new text of the cell if it applies to given event.</param>
/// <param name="isUserCanceled">Indicates whether action is canceled by the end user.</param>
public CellEditEventArgs(Cell cell, eTreeAction action, string newText, bool isUserCanceled, ICellEditControl editor)
{
this.Action = action;
this.Cell = cell;
this.NewText = newText;
this.IsUserCanceled = isUserCanceled;
_Editor = editor;
}
}
}

View File

@ -0,0 +1,570 @@
using System;
using System.Drawing;
using System.ComponentModel;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents class that holds images for a cell.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[ToolboxItem(false), TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class CellImages
{
// Image variables
private System.Drawing.Image m_Image=null;
private System.Drawing.Image m_DisabledImageGenerated = null;
private int m_ImageIndex=-1; // Image index if image from ImageList is used
private System.Drawing.Image m_ImageMouseOver=null;
private int m_ImageMouseOverIndex=-1; // Image index if image from ImageList is used
private System.Drawing.Image m_ImageDisabled=null;
// private bool m_DisabledImageCustom=false;
private int m_ImageDisabledIndex=-1; // Image index if image from ImageList is used
private System.Drawing.Image m_ImageExpanded=null;
private int m_ImageExpandedIndex=-1;
private Cell m_ParentCell=null;
private Size m_LargestImageSize=Size.Empty;
/// <summary>
/// Initializes new instance of CellImages class.
/// </summary>
/// <param name="parentCell">Reference to parent cell.</param>
public CellImages(Cell parentCell)
{
m_ParentCell=parentCell;
}
#region Properties
internal System.Drawing.Image DisabledImageGenerated
{
get { return m_DisabledImageGenerated; }
set
{
m_DisabledImageGenerated = value;
}
}
/// <summary>
/// Gets or sets default cell image. Setting this property to valid image will
/// override any setting of ImageIndex property.
/// </summary>
/// <remarks>
/// <para>The image set through this property will be serialized with the cell. If you
/// plan to use ImageList then use <see cref="ImageIndex">ImageIndex</see>
/// property.</para>
/// <para>
/// <para>If you plan to use alpha-blended images we recommend using PNG-24 format
/// which supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1
/// do not support alpha-blending when used through Image class.</para>
/// </para>
/// </remarks>
/// <value>Image object or <strong>null (Nothing)</strong> if no image is assigned.</value>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates default cell image"), DevCoSerialize()]
public System.Drawing.Image Image
{
get {return m_Image;}
set
{
ChangeImage(ref m_Image, value);
}
}
/// <summary>
/// Resets Image property to it's default value (null, VB nothing).
/// </summary>
public void ResetImage()
{
TypeDescriptor.GetProperties(this)["Image"].SetValue(this, null);
}
/// <summary>
/// Gets or sets the image that is displayed when mouse is over the cell. Setting
/// this property to valid image will override any setting of ImageMouseOverIndex
/// property.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()]
public System.Drawing.Image ImageMouseOver
{
get {return m_ImageMouseOver;}
set
{
ChangeImage(ref m_ImageMouseOver, value);
}
}
/// <summary>
/// Resets ImageMouseOver to it's default value (null, VB nothing).
/// </summary>
public void ResetImageMouseOver()
{
TypeDescriptor.GetProperties(this)["ImageMouseOver"].SetValue(this, null);
}
/// <summary>
/// Gets or sets the image that is displayed when cell is disabled. If not assigned
/// disabled image is created from default cell image. Setting this property to valid image
/// will override any setting of ImageDisabledIndex property.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true), DefaultValue(null), Category("Images"), Description("Indicates disabled cell image")]
public System.Drawing.Image ImageDisabled
{
get { return m_ImageDisabled; }
set
{
ChangeImage(ref m_ImageDisabled, value);
}
}
/// <summary>
/// Resets ImageDisabled to it's default value (null, VB nothing).
/// </summary>
public void ResetImageDisabled()
{
this.ImageDisabled = null;
}
/// <summary>
/// Gets or sets image that is displayed when Node that this cell belongs to is
/// expanded. Setting this property to valid image will override any setting of
/// ImageExpandedIndex property.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates cell image when node associtaed with this cell is expanded"), DevCoSerialize()]
public System.Drawing.Image ImageExpanded
{
get {return m_ImageExpanded;}
set
{
ChangeImage(ref m_ImageExpanded, value);
}
}
/// <summary>
/// Resets ImageExpanded to it's default value (null, VB nothing).
/// </summary>
public void ResetImageExpanded()
{
TypeDescriptor.GetProperties(this)["ImageExpanded"].SetValue(this, null);
}
/// <summary>
/// Gets or sets the Index of default cell image from ImageList specified on AdvTree
/// control.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates default cell image"), DevCoSerialize()]
public int ImageIndex
{
get {return m_ImageIndex;}
set
{
m_ImageIndex=value;
this.OnImageChanged();
}
}
private string _ImageKey = "";
/// <summary>
/// Gets or sets the key of the default cell image from ImageList specified on AdvTree control.
/// </summary>
[DefaultValue(""), Category("ImageList Images"), Description("Indicates the default cell image key"), DevCoSerialize()]
public string ImageKey
{
get { return _ImageKey; }
set
{
_ImageKey = value;
this.OnImageChanged();
}
}
/// <summary>
/// Property Editor support for ImageIndex selection
/// </summary>
[System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public System.Windows.Forms.ImageList ImageList
{
get
{
if(this.Parent!=null)
{
AdvTree tree=this.Parent.TreeControl;
if(tree!=null)
{
return tree.ImageList;
}
}
return null;
}
}
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the Index of cell image when mouse is over the cell from ImageList
/// specified on AdvTree control.
/// </summary>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()]
public int ImageMouseOverIndex
{
get {return m_ImageMouseOverIndex;}
set
{
m_ImageMouseOverIndex=value;
this.OnImageChanged();
}
}
private string _ImageMouseOverKey = "";
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the key of cell image when mouse is over the cell from ImageList
/// specified on AdvTree control.
/// </summary>
[Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()]
public string ImageMouseOverKey
{
get { return _ImageMouseOverKey; }
set
{
_ImageMouseOverKey = value;
this.OnImageChanged();
}
}
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the Index of disabled cell image from ImageList specified on AdvTree
/// control.
/// </summary>
[Browsable(true), DefaultValue(-1), Category("ImageList Images"), Description("Indicates disabled cell image")]
public int ImageDisabledIndex
{
get { return m_ImageDisabledIndex; }
set
{
m_ImageDisabledIndex = value;
this.OnImageChanged();
}
}
private string _ImageDisabledKey = "";
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the key of disabled cell image from ImageList specified on AdvTree
/// control.
/// </summary>
[Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates disabled cell image")]
public string ImageDisabledKey
{
get { return _ImageDisabledKey; }
set
{
_ImageDisabledKey = value;
this.OnImageChanged();
}
}
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the Index of cell image from ImageList specified on AdvTree control
/// that is used when Node associated with this cell is expanded
/// </summary>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates expanded cell image"), DevCoSerialize()]
public int ImageExpandedIndex
{
get {return m_ImageExpandedIndex;}
set
{
m_ImageExpandedIndex=value;
this.OnImageChanged();
}
}
private string _ImageExpandedKey = "";
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the key of cell image from ImageList specified on AdvTree control
/// that is used when Node associated with this cell is expanded
/// </summary>
[Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates expanded cell image"), DevCoSerialize()]
public string ImageExpandedKey
{
get { return _ImageExpandedKey; }
set
{
_ImageExpandedKey = value;
this.OnImageChanged();
}
}
/// <summary>
/// Gets or sets the parent node of the cell.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Cell Parent
{
get {return m_ParentCell;}
set {m_ParentCell=value;}
}
/// <summary>
/// Gets whether CellImages object should be serialized or not. If object has all
/// default values then this property will return <strong>false</strong>.
/// </summary>
internal bool ShouldSerialize
{
get
{
if(m_Image==null && m_ImageDisabled==null && m_ImageDisabledIndex==-1 &&
m_ImageExpanded==null && m_ImageExpandedIndex==-1 && m_ImageIndex==-1 &&
m_ImageMouseOver==null && m_ImageMouseOverIndex==-1)
return false;
return true;
}
}
/// <summary>
/// Returns largest image size in this set of images.
/// </summary>
internal Size LargestImageSize
{
get
{
return m_LargestImageSize;
}
}
#endregion
#region Methods
/// <summary>Makes a copy of a CellImages object.</summary>
public virtual CellImages Copy()
{
CellImages ci=new CellImages(null);
ci.Image=this.Image;
// ci.ImageDisabled=this.ImageDisabled;
// ci.ImageDisabledIndex=this.ImageDisabledIndex;
ci.ImageExpanded = this.ImageExpanded == null ? null : (Image) this.ImageExpanded.Clone();
ci.ImageExpandedIndex=this.ImageExpandedIndex;
ci.ImageIndex=this.ImageIndex;
ci.ImageMouseOver=this.ImageMouseOver == null? null : (Image)this.ImageMouseOver.Clone();
ci.ImageMouseOverIndex=this.ImageMouseOverIndex;
ci.ImageDisabledKey = this.ImageDisabledKey;
ci.ImageExpandedKey = this.ImageExpandedKey;
ci.ImageKey = this.ImageKey;
ci.ImageMouseOverKey = this.ImageMouseOverKey;
return ci;
}
#endregion
#region Internals
/// <summary>
/// Changes the image and invokes largest image size calculation if the
/// image size truly changed.
/// </summary>
/// <param name="currentImage"></param>
/// <param name="newImage"></param>
private void ChangeImage(ref System.Drawing.Image currentImage, System.Drawing.Image newImage)
{
// Early out if no real change
if (currentImage == newImage)
return;
// Hold onto previous image
System.Drawing.Image previousImage = currentImage;
// Assign new image
currentImage = newImage;
// If either current or previous is null, or the sizes don't match,
// we need to resize ourselves and the parent.
if (previousImage == null || currentImage == null || GetImageSize(previousImage) != GetImageSize(currentImage))
{
RefreshLargestImageSize();
if (this.Parent != null)
this.Parent.OnImageChanged();
}
// Dispose the generated disabled image, if applicable.
DisposeGeneratedDisabledImage();
}
private Size GetImageSize(Image image)
{
try
{
return image.Size;
}
catch
{
return Size.Empty;
}
}
private void OnImageChanged()
{
RefreshLargestImageSize();
if (this.Parent != null)
this.Parent.OnImageChanged();
DisposeGeneratedDisabledImage();
}
public void Dispose()
{
DisposeGeneratedDisabledImage();
if (BarUtilities.DisposeItemImages || _AutoDispose)
{
BarUtilities.DisposeImage(ref m_Image);
BarUtilities.DisposeImage(ref m_ImageDisabled);
BarUtilities.DisposeImage(ref m_ImageExpanded);
BarUtilities.DisposeImage(ref m_ImageMouseOver);
}
}
internal void DisposeGeneratedDisabledImage()
{
if (m_DisabledImageGenerated != null)
{
m_DisabledImageGenerated.Dispose();
m_DisabledImageGenerated = null;
}
}
internal void RefreshLargestImageSize()
{
m_LargestImageSize=Size.Empty;
AdjustSize(m_Image,ref m_LargestImageSize);
AdjustSize(m_ImageDisabled,ref m_LargestImageSize);
AdjustSize(m_ImageExpanded,ref m_LargestImageSize);
AdjustSize(m_ImageMouseOver,ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageIndex),ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageDisabledIndex),ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageExpandedIndex),ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageMouseOverIndex),ref m_LargestImageSize);
AdjustSize(GetImageByKey(_ImageKey), ref m_LargestImageSize);
AdjustSize(GetImageByKey(_ImageDisabledKey), ref m_LargestImageSize);
AdjustSize(GetImageByKey(_ImageExpandedKey), ref m_LargestImageSize);
AdjustSize(GetImageByKey(_ImageMouseOverKey), ref m_LargestImageSize);
}
private void AdjustSize(System.Drawing.Image image, ref Size size)
{
if(image!=null)
{
if(image.Width>size.Width)
size.Width=image.Width;
if(image.Height>size.Height)
size.Height=image.Height;
}
}
/// <summary>
/// Returns image from image list based on the image index.
/// </summary>
/// <param name="imageIndex">Index of the image to return.</param>
/// <returns>Image object from image list.</returns>
internal System.Drawing.Image GetImageByIndex(int imageIndex)
{
if (imageIndex >= 0 && this.Parent != null && this.Parent.TreeControl != null && this.Parent.TreeControl.ImageList != null && this.Parent.TreeControl.ImageList.Images.Count > 0)
{
try
{
return this.Parent.TreeControl.ImageList.Images[imageIndex];
}
catch
{
return null;
}
}
else
return null;
}
/// <summary>
/// Returns image from image list based on the image key.
/// </summary>
/// <param name="key">Key of the image to return.</param>
/// <returns>Image object from image list.</returns>
internal System.Drawing.Image GetImageByKey(string key)
{
if (string.IsNullOrEmpty(key)) return null;
Cell parent = this.Parent;
if (parent == null) return null;
AdvTree tree = parent.TreeControl;
if (tree == null || tree.ImageList == null || !tree.ImageList.Images.ContainsKey(key)) return null;
return tree.ImageList.Images[key];
}
private bool _AutoDispose = false;
/// <summary>
/// Indicates whether assigned images are automatically disposed when the cell and node are disposed. Default value is false.
/// </summary>
[Browsable(false), DefaultValue(false)]
public bool AutoDispose
{
get { return _AutoDispose; }
set
{
_AutoDispose = value;
}
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,583 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents collection for ColumnHeader objects.
/// </summary>
public class ColumnHeaderCollection : CollectionBase
{
#region Private Variables
private Node _ParentNode = null;
private AdvTree _Parent = null;
#endregion
#region Internal Implementation
/// <summary>
/// Default constructor.
/// </summary>
public ColumnHeaderCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get { return _ParentNode; }
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">ColumnHeader that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
_ParentNode = parent;
}
internal AdvTree Parent
{
get { return _Parent; }
set { _Parent = value; }
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="ch">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(ColumnHeader ch)
{
return List.Add(ch);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public ColumnHeader this[int index]
{
get { return (ColumnHeader)(List[index]); }
set { List[index] = value; }
}
/// <summary>
/// Returns reference to the object in collection based on it's name.
/// </summary>
public ColumnHeader this[string name]
{
get
{
int index = IndexOf(name);
if (index == -1) return null;
return this[index];
}
set { this[IndexOf(name)] = value; }
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, ColumnHeader value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(ColumnHeader value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="name">Name of column to return index for.</param>
/// <returns>Index of the column or -1 if column not found.</returns>
public int IndexOf(string name)
{
for (int i = 0; i < this.List.Count; i++)
{
if (this[i].Name == name) return i;
}
return -1;
}
/// <summary>
/// Returns index of the object inside of the collection based on column DataFieldName.
/// </summary>
/// <param name="dataFieldName">DataFieldName of column to return index for.</param>
/// <returns>Index of the column or -1 if column not found.</returns>
public int IndexOfDataField(string dataFieldName)
{
dataFieldName = dataFieldName.ToLower();
for (int i = 0; i < this.List.Count; i++)
{
if (this[i].DataFieldName.ToLower() == dataFieldName) return i;
}
return -1;
}
/// <summary>
/// Returns index of the object inside of the collection based on column DataFieldName.
/// </summary>
/// <param name="fieldName">DataFieldName of column to return index for.</param>
/// <returns>Index of the column or -1 if column not found.</returns>
internal int IndexOfField(string fieldName)
{
fieldName = fieldName.ToLower();
for (int i = 0; i < this.List.Count; i++)
{
ColumnHeader header = this[i];
if (header.Tag is BindingMemberInfo && ((BindingMemberInfo)header.Tag).BindingField.ToLower() == fieldName)
return i;
if (header.DataFieldName.ToLower() == fieldName) return i;
if (header.Name == fieldName) return i;
}
return -1;
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(ColumnHeader value)
{
return List.Contains(value);
}
protected override void OnSet(int index, object oldValue, object newValue)
{
if (oldValue is ColumnHeader)
{
ColumnHeader header = (ColumnHeader)oldValue;
if (header.SortDirection != eSortDirection.None) IsSorted = false;
}
if (newValue is ColumnHeader)
{
ColumnHeader header = (ColumnHeader)newValue;
if (header.SortDirection != eSortDirection.None) IsSorted = true;
}
base.OnSet(index, oldValue, newValue);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(ColumnHeader value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index, object value)
{
if (value is ColumnHeader)
{
ColumnHeader header = (ColumnHeader)value;
if (header.SortDirection != eSortDirection.None) IsSorted = false;
header.HeaderSizeChanged -= new EventHandler(this.HeaderSizeChanged);
header.SortCells -= new SortCellsEventHandler(SortCellsHandler);
header.MouseDown -= new System.Windows.Forms.MouseEventHandler(ColumnMouseDown);
header.MouseUp -= new System.Windows.Forms.MouseEventHandler(ColumnMouseUp);
header.Parent = null;
}
InvalidateDisplayIndexes();
UpdateTreeLayout();
base.OnRemoveComplete(index, value);
}
protected override void OnInsertComplete(int index, object value)
{
if (value is ColumnHeader)
{
((ColumnHeader)value).HeaderSizeChanged += new EventHandler(this.HeaderSizeChanged);
((ColumnHeader)value).SortCells += new SortCellsEventHandler(SortCellsHandler);
((ColumnHeader)value).MouseDown += new System.Windows.Forms.MouseEventHandler(ColumnMouseDown);
((ColumnHeader)value).MouseUp += new System.Windows.Forms.MouseEventHandler(ColumnMouseUp);
((ColumnHeader)value).Parent = this;
}
InvalidateDisplayIndexes();
UpdateTreeLayout();
base.OnInsertComplete(index, value);
}
[System.Reflection.Obfuscation(Exclude = true)]
private void ColumnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
AdvTree tree = GetTree();
if (tree != null)
tree.InvokeColumnHeaderMouseUp(sender, e);
}
[System.Reflection.Obfuscation(Exclude = true)]
private void ColumnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
AdvTree tree = GetTree();
if (tree != null)
tree.InvokeColumnHeaderMouseDown(sender, e);
}
private AdvTree GetTree()
{
AdvTree tree = _Parent;
if (tree == null && _ParentNode != null)
tree = _ParentNode.TreeControl;
return tree;
}
/// <summary>
/// Occurs before the cells are sorted.
/// </summary>
[Description("Occurs before the cells are sorted.")]
public event SortCellsEventHandler SortCells;
protected virtual void OnSortCells(SortEventArgs e)
{
if (SortCells != null)
SortCells(this, e);
}
private void SortCellsHandler(object sender, SortEventArgs e)
{
ColumnHeader ch = (ColumnHeader)sender;
int i = this.IndexOf(ch);
IComparer comparer = null;
if (e.ReverseSort)
{
if (ch.SortComparerReverse != null)
comparer = ch.SortComparerReverse;
else
comparer = new NodeComparerReverse(i);
}
else
{
if (ch.SortComparer != null)
comparer = ch.SortComparer;
else
comparer = new NodeComparer(i);
}
if (e.Comparer == null)
e.Comparer = comparer;
else
comparer = e.Comparer;
OnSortCells(e);
if (e.Cancel)
return;
if (_Parent != null)
{
_Parent.Nodes.Sort(comparer);
}
else if (_ParentNode != null)
_ParentNode.Nodes.Sort(comparer);
}
private bool _UpdatingSortDirection = false;
/// <summary>
/// Called when SortDirection property on column header is set to value other than None.
/// </summary>
/// <param name="header">Ref to column header</param>
internal void SortDirectionUpdated(ColumnHeader header)
{
if (_UpdatingSortDirection) return;
_UpdatingSortDirection = true;
try
{
if (header.SortDirection == eSortDirection.None)
{
IsSorted = false;
return;
}
IsSorted = true;
foreach (ColumnHeader col in this.List)
{
if (col != header && col.SortDirection != eSortDirection.None)
col.SortDirection = eSortDirection.None;
}
}
finally
{
_UpdatingSortDirection = false;
}
}
private bool _IsSorted;
/// <summary>
/// Gets whether a column that is part of this collection has SortDirection set.
/// </summary>
public bool IsSorted
{
get { return _IsSorted; }
internal set { _IsSorted = value; }
}
internal void UpdateSort()
{
if (!_IsSorted) return;
foreach (ColumnHeader header in this.List)
{
if (header.SortDirection != eSortDirection.None)
{
header.Sort(header.SortDirection == eSortDirection.Descending);
break;
}
}
}
private void UpdateTreeLayout()
{
if (_Parent != null)
{
_Parent.InvalidateNodesSize();
_Parent.Invalidate();
if (_Parent.Nodes.Count == 0)
_Parent.RecalcLayout();
else
_Parent.SetPendingLayout();
}
else if (_ParentNode != null)
{
AdvTree tree = _ParentNode.TreeControl;
if (tree != null)
{
tree.InvalidateNodeSize(_ParentNode);
tree.Invalidate();
}
}
}
private void HeaderSizeChanged(object sender, EventArgs e)
{
UpdateTreeLayout();
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(ColumnHeader[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColumnHeader array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(ColumnHeader[] array)
{
List.CopyTo(array, 0);
}
protected override void OnClear()
{
foreach (ColumnHeader item in this)
{
item.HeaderSizeChanged -= new EventHandler(this.HeaderSizeChanged);
item.SortCells -= new SortCellsEventHandler(SortCellsHandler);
item.MouseDown -= new System.Windows.Forms.MouseEventHandler(ColumnMouseDown);
item.MouseUp -= new System.Windows.Forms.MouseEventHandler(ColumnMouseUp);
item.Parent = null;
}
IsSorted = false;
base.OnClear();
}
/// <summary>
/// A map of display index (key) to index in the column collection (value). Used to quickly find a column from its display index.
/// </summary>
internal List<int> DisplayIndexMap
{
get
{
if (!_IsDisplayIndexValid)
{
UpdateDisplayIndexMap();
}
return _DisplayIndexMap;
}
}
/// <summary>
/// Gets the display index for specified column.
/// </summary>
/// <param name="column">Column that is part f ColumnHeaderCollection</param>
/// <returns>Display index or -1 column is not part of this collection.</returns>
public int GetDisplayIndex(ColumnHeader column)
{
int index = this.IndexOf(column);
UpdateDisplayIndexMap();
for (int i = 0; i < _DisplayIndexMap.Count; i++)
{
if (_DisplayIndexMap[i] == index) return i;
}
return -1;
}
/// <summary>
/// Returns the column that is displayed at specified display index..
/// </summary>
/// <param name="displayIndex">0 based display index.</param>
/// <returns>ColumnHeader</returns>
public ColumnHeader ColumnAtDisplayIndex(int displayIndex)
{
UpdateDisplayIndexMap();
return this[_DisplayIndexMap[displayIndex]];
}
private List<int> _DisplayIndexMap = new List<int>();
private bool _IsDisplayIndexValid = false;
private void UpdateDisplayIndexMap()
{
if (_IsDisplayIndexValid) return;
_IsDisplayIndexValid = true;
_DisplayIndexMap.Clear();
List<IndexToDisplayIndex> workingMap = new List<IndexToDisplayIndex>();
bool isAllDefault = true;
for (int i = 0; i < Count; i++)
{
int displayIndex = this[i].DisplayIndex;
if (displayIndex != -1) isAllDefault = false;
workingMap.Add(new IndexToDisplayIndex(i, displayIndex));
}
if (!isAllDefault)
workingMap.Sort(new DisplayIndexComparer());
foreach (IndexToDisplayIndex item in workingMap)
{
_DisplayIndexMap.Add(item.Index);
}
}
/// <summary>
/// Gets reference to last visible column or null if there is no last visible column.
/// </summary>
public DevComponents.AdvTree.ColumnHeader LastVisibleColumn
{
get
{
List<int> displayMap = DisplayIndexMap;
for (int i = displayMap.Count - 1; i >=0; i--)
{
if (this[displayMap[i]].Visible) return this[displayMap[i]];
}
return null;
}
}
/// <summary>
/// Gets reference to first visible column or null if there is no first visible column.
/// </summary>
public DevComponents.AdvTree.ColumnHeader FirstVisibleColumn
{
get
{
List<int> displayMap = DisplayIndexMap;
for (int i = 0; i < displayMap.Count; i++)
{
if (this[displayMap[i]].Visible) return this[displayMap[i]];
}
return null;
}
}
#region IndexToDisplayIndex Class
private class IndexToDisplayIndex
{
public int Index = -1;
public int DisplayIndex = -1;
/// <summary>
/// Initializes a new instance of the IndexToDisplayIndex class.
/// </summary>
/// <param name="index"></param>
/// <param name="displayIndex"></param>
public IndexToDisplayIndex(int index, int displayIndex)
{
Index = index;
DisplayIndex = displayIndex;
}
}
#endregion
#region DisplayIndexComparer
private class DisplayIndexComparer : IComparer<IndexToDisplayIndex>
{
#region IComparer<IndexToDisplayIndex> Members
public int Compare(IndexToDisplayIndex x, IndexToDisplayIndex y)
{
if (x.DisplayIndex == y.DisplayIndex)
{
return x.Index - y.Index;
}
else
{
return x.DisplayIndex - y.DisplayIndex;
}
}
#endregion
}
#endregion
internal void DisplayIndexChanged(ColumnHeader column, int newDisplayIndex, int oldDisplayIndex)
{
InvalidateDisplayIndexes();
if (_UpdatingDisplayIndexes) return;
if (_Parent != null && !_Parent.IsUpdateSuspended)
UpdateTreeLayout();
else if (_ParentNode != null && _ParentNode.TreeControl != null && !_ParentNode.TreeControl.IsUpdateSuspended)
UpdateTreeLayout();
}
/// <summary>
/// Invalidates the display indexes and causes them to be re-evaluated on next layout.
/// </summary>
public void InvalidateDisplayIndexes()
{
_IsDisplayIndexValid = false;
}
#endregion
private Rectangle _Bounds = Rectangle.Empty;
internal void SetBounds(System.Drawing.Rectangle totalBounds)
{
_Bounds = totalBounds;
}
/// <summary>
/// Gets the column header rendering bounds.
/// </summary>
[Browsable(false)]
public Rectangle Bounds
{
get { return _Bounds; }
}
internal bool UsesRelativeSize = false;
private bool _UpdatingDisplayIndexes = false;
internal bool UpdatingDisplayIndexes
{
get { return _UpdatingDisplayIndexes; }
set { _UpdatingDisplayIndexes = value; }
}
}
}

View File

@ -0,0 +1,324 @@
using System;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using DevComponents.DotNetBar;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace DevComponents.AdvTree
{
internal class ColumnHeaderControl : Control
{
#region Constructor
/// <summary>
/// Initializes a new instance of the ColumnHeaderControl class.
/// </summary>
public ColumnHeaderControl()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.Selectable, false);
this.SetStyle(ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, true);
}
#endregion
#region Internal Implementation
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
DisplayHelp.FillRectangle(g, this.ClientRectangle, this.BackColor);
if (_Columns == null)
{
return;
}
AdvTree tree = GetTree();
if (tree != null)
{
SmoothingMode sm = g.SmoothingMode;
TextRenderingHint th = g.TextRenderingHint;
if (tree.AntiAlias)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
}
//Creates the drawing matrix with the right zoom;
if (tree.Zoom != 1)
{
System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(tree.Zoom);
//use it for drawing
g.Transform = mx;
}
tree.NodeDisplay.PaintColumnHeaders(_Columns, g, true);
int columnMoveMarkerIndex = _ColumnMoveMarkerIndex;
if (columnMoveMarkerIndex >= 0)
DevComponents.AdvTree.Display.ColumnHeaderDisplay.PaintColumnMoveMarker(g, tree, columnMoveMarkerIndex, _Columns);
if (tree.AntiAlias)
{
g.SmoothingMode = sm;
g.TextRenderingHint = th;
}
}
base.OnPaint(e);
}
private int _ColumnMoveMarkerIndex = -1;
/// <summary>
/// Gets or sets the column move marker that marks insertion point for column that is dragged. Marker is drawn before the column specified by this index.
/// </summary>
internal int ColumnMoveMarkerIndex
{
get { return _ColumnMoveMarkerIndex; }
set
{
_ColumnMoveMarkerIndex = value;
this.Invalidate();
}
}
/// <summary>
/// Returns mouse position which is translated if control Zoom is not equal 1
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <returns></returns>
private Point GetLayoutPosition(float zoom, int x, int y)
{
if (zoom == 1)
return new Point(x, y);
Point[] p = new Point[] { new Point(x, y) };
using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(zoom))
{
mx.Invert();
mx.TransformPoints(p);
}
return p[0];
}
private System.Drawing.Drawing2D.Matrix GetTranslationMatrix(float zoom)
{
System.Drawing.Drawing2D.Matrix mx = new System.Drawing.Drawing2D.Matrix(zoom, 0, 0, zoom, 0, 0);
return mx;
}
private AdvTree GetTree()
{
return this.Parent as AdvTree;
}
private ColumnHeaderCollection _Columns = null;
/// <summary>
/// Gets or sets the column header collection to be rendered.
/// </summary>
public ColumnHeaderCollection Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private Cursor _OldCursor = null;
private ColumnHeader _MouseOverColumnHeader = null;
protected override void OnMouseMove(MouseEventArgs e)
{
AdvTree tree = GetTree();
Point p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (_MouseOverColumnHeader != ch)
{
if (_MouseOverColumnHeader != null)
_MouseOverColumnHeader.InternalMouseLeave(e);
_MouseOverColumnHeader = ch;
if (_MouseOverColumnHeader != null)
{
_MouseOverColumnHeader.InternalMouseEnter(e);
Interop.WinApi.ResetHover(this);
}
}
if (ch != null)
{
ch.InternalMouseMove(e);
}
if (e.Button == MouseButtons.Left && _MouseDownHeader != null && tree.AllowUserToReorderColumns && (Math.Abs(_MouseDownPoint.X-e.X)>1))
{
tree.StartColumnReorder(p.X, p.Y);
return;
}
if (tree == null || e.Button != MouseButtons.None || !tree.AllowUserToResizeColumns) return;
if (tree.CanResizeColumnAt(p.X, p.Y))
{
if (_OldCursor == null)
{
_OldCursor = this.Cursor;
this.Cursor = Cursors.VSplit;
}
}
else
{
ReleaseCursor();
}
base.OnMouseMove(e);
}
ColumnHeader _MouseDownHeader = null;
private Point _MouseDownPoint = Point.Empty;
protected override void OnMouseDown(MouseEventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
bool canResize = false;
_MouseDownPoint = e.Location;
if (tree != null)
{
p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
}
if (tree != null && tree.AllowUserToResizeColumns && e.Button == MouseButtons.Left)
canResize = tree.CanResizeColumnAt(p.X, p.Y);
if (tree != null)
{
p = GetLayoutPosition(tree.Zoom, e.X, e.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
_MouseDownHeader = ch;
if (!canResize)
ch.OnMouseDown(e);
}
}
if (tree == null || e.Button != MouseButtons.Left || !tree.AllowUserToResizeColumns) return;
if (canResize)
{
tree.StartColumnResize(p.X, p.Y);
}
this.Invalidate();
base.OnMouseDown(e);
}
protected override void OnMouseHover(EventArgs e)
{
if (Control.MouseButtons == MouseButtons.None)
{
AdvTree tree = GetTree();
Point p = this.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, p.X, p.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
ch.InternalMouseHover(e);
}
}
base.OnMouseHover(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
ReleaseCursor();
_MouseDownPoint = Point.Empty;
if (_MouseDownHeader!=null)
{
_MouseDownHeader.OnMouseUp(e);
_MouseDownHeader = null;
}
this.Invalidate();
base.OnMouseUp(e);
}
protected override void OnClick(EventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
if (tree != null)
{
Point tp = tree.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
ch.OnClick(e);
}
}
this.Invalidate();
base.OnClick(e);
}
internal DateTime IgnoreDoubleClickTime = DateTime.MinValue;
protected override void OnDoubleClick(EventArgs e)
{
AdvTree tree = GetTree();
Point p = Point.Empty;
if (tree != null)
{
Point tp = tree.PointToClient(Control.MousePosition);
p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y);
ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns);
if (ch != null)
{
DateTime now = DateTime.Now;
if (IgnoreDoubleClickTime != DateTime.MinValue && now.Subtract(IgnoreDoubleClickTime).TotalMilliseconds <= SystemInformation.DoubleClickTime)
{
IgnoreDoubleClickTime = DateTime.MinValue;
return;
}
IgnoreDoubleClickTime = DateTime.MinValue;
ch.OnDoubleClick(e);
}
}
this.Invalidate();
base.OnDoubleClick(e);
}
private void ReleaseCursor()
{
if (_OldCursor != null)
{
this.Cursor = _OldCursor;
_OldCursor = null;
}
}
protected override void OnMouseLeave(EventArgs e)
{
if (_MouseOverColumnHeader != null)
{
_MouseOverColumnHeader.InternalMouseLeave(e);
_MouseOverColumnHeader = null;
}
if (Control.MouseButtons != MouseButtons.Left)
ReleaseCursor();
base.OnMouseLeave(e);
}
#endregion
}
}

View File

@ -0,0 +1,151 @@
using System;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents the width of the Column. Supports absolute width in Pixels and
/// relative width as percentage of the width of parent control.
/// </summary>
[ToolboxItem(false) ,System.ComponentModel.DesignTimeVisible(false),TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class ColumnWidth
{
private int m_Relative=0;
private int m_Absolute=0;
internal event EventHandler WidthChanged;
/// <summary>
/// Creates new instance of the object.
/// </summary>
public ColumnWidth()
{
}
/// <summary>
/// Gets or sets relative width expressed as percentage between 1-100. 0 indicates that
/// absolute width will be used.
/// </summary>
/// <remarks>
/// Relative width is expressed as percentage between 1-100 of the parent controls
/// width. 0 indicates that absolute width will be used. Absolute width always takes
/// priority over relative width. For example value of 30 assigned to this property
/// indicates that width of the column will be 30% of the total client width of the
/// control.
/// </remarks>
[DefaultValue(0),Browsable(true),Description("Gets or sets relative width in percent. Valid values are between 1-100 with 0 indicating that absolute width will be used.")]
public int Relative
{
get {return m_Relative;}
set
{
if(m_Relative!=value)
{
m_Relative=value;
OnSizeChanged();
}
}
}
/// <summary>Gets or sets the absolute width of the column in pixels.</summary>
/// <remarks>
/// Absolute width always takes precedence over the relative width of the
/// column.
/// </remarks>
[DefaultValue(0),Browsable(true),Description("Gets or sets the absolute width of the column in pixels.")]
public int Absolute
{
get {return m_Absolute;}
set
{
if(m_Absolute<0)
return;
if(m_Absolute!=value)
{
m_Absolute=value;
if(m_Absolute!=0)
m_Relative=0;
OnSizeChanged();
}
}
}
internal void SetAbsolute(int value)
{
m_Absolute = value;
}
internal int GetWidth(int containerWidth)
{
if (m_Absolute > 0)
return m_Absolute;
if(m_Relative>0)
return (100 / m_Relative) * containerWidth;
return 0;
}
private void OnSizeChanged()
{
if(WidthChanged!=null)
WidthChanged(this,new EventArgs());
}
private bool _AutoSize = false;
/// <summary>
/// Gets or sets whether column width is automatically set based on the column's content. Default value is false.
/// When set absolute and relative size values are ignored.
/// </summary>
[DefaultValue(false), Description("Indicates whether column is sized based on the content.")]
public bool AutoSize
{
get { return _AutoSize; }
set
{
if (_AutoSize != value)
{
_AutoSize = value;
OnSizeChanged();
}
}
}
internal void SetAutoSize(bool autoSize)
{
_AutoSize = autoSize;
}
private bool _AutoSizeMinHeader = false;
/// <summary>
/// Gets or sets whether column auto-width is set to minimum of the column header text width. Applies to AutoSize=true only.
/// </summary>
[DefaultValue(false), Description("Indicates whether column auto-width is set to minimum of the column header text width. Applies to AutoSize=true only.")]
public bool AutoSizeMinHeader
{
get { return _AutoSizeMinHeader; }
set
{
_AutoSizeMinHeader = value;
OnSizeChanged();
}
}
private int _AutoSizeWidth = 0;
/// <summary>
/// Gets the auto-size calculated width of the column after tree layout is performed and column has AutoSize=true.
/// </summary>
[Browsable(false)]
public int AutoSizeWidth
{
get { return _AutoSizeWidth; }
// internal set
// {
// _AutoSizeWidth = value;
// }
}
internal void SetAutoSizeWidth(int value)
{
_AutoSizeWidth = value;
}
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides event arguments for command button events.
/// </summary>
public class CommandButtonEventArgs:EventArgs
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="action">Action type.</param>
/// <param name="node">Context node.</param>
public CommandButtonEventArgs(eTreeAction action, Node node)
{
this.Action=action;
this.Node=node;
}
/// <summary>
/// Indicates the action type that caused the event.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the node action is peformed on.
/// </summary>
public DevComponents.AdvTree.Node Node=null;
}
}

View File

@ -0,0 +1,154 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents collection of connector points for a node.
/// </summary>
public class ConnectorPointsCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>
/// Default constructor.
/// </summary>
public ConnectorPointsCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Node that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="p">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(Point p)
{
return List.Add(p);
}
/// <summary>
/// Adds range of objects to the array.
/// </summary>
/// <param name="ap">Array to add.</param>
public void AddRange(Point[] ap)
{
foreach(Point p in ap)
this.Add(p);
}
/// <summary>
/// Copies objects of the collection to the array.
/// </summary>
/// <returns></returns>
public Point[] ToArray()
{
Point[] ap=new Point[this.Count];
this.CopyTo(ap);
return ap;
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Point this[int index]
{
get {return (Point)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, Point value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Point value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Point value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(Point value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Point[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColumnHeader array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(Point[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
}

View File

@ -0,0 +1,243 @@
using System;
using System.Text;
using DevComponents.Editors;
using System.Windows.Forms;
using DevComponents.Editors.DateTimeAdv;
namespace DevComponents.AdvTree
{
#if FRAMEWORK20
#region Integer Custom Editor
internal class IntegerCellEditor : IntegerInput, ICellEditControl
{
#region ICellEditControl Members
public void BeginEdit()
{
#if (FRAMEWORK20)
this.MinimumSize = new System.Drawing.Size(32, 10);
#endif
}
public void EndEdit()
{
this.Dispose();
}
public object CurrentValue
{
get
{
if (this.FreeTextEntryMode && this.IsKeyboardFocusWithin)
this.ApplyFreeTextValue();
return this.Text;
}
set
{
if (value is int)
this.Value = (int)value;
else if (value == null)
this.ValueObject = null;
else
{
string s = Utilities.StripNonNumeric(value.ToString());
int i = 0;
#if FRAMEWORK20
int.TryParse(s, out i);
#else
try
{
i = int.Parse(s);
}
catch { }
#endif
this.Value = i;
}
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter || keyData == Keys.Tab)
{
if (EditComplete != null)
EditComplete(this, new EventArgs());
return true;
}
else if (keyData == Keys.Escape)
{
if (CancelEdit != null)
CancelEdit(this, new EventArgs());
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
public event EventHandler EditComplete;
public event EventHandler CancelEdit;
public bool EditWordWrap
{
get { return false; }
set { }
}
#endregion
}
#endregion
#region Double Custom Editor
internal class DoubleCellEditor : DoubleInput, ICellEditControl
{
#region ICellEditControl Members
public void BeginEdit()
{
#if (FRAMEWORK20)
this.MinimumSize = new System.Drawing.Size(32, 10);
#endif
}
public void EndEdit()
{
this.Dispose();
}
public object CurrentValue
{
get
{
if (this.FreeTextEntryMode && this.IsKeyboardFocusWithin)
this.ApplyFreeTextValue();
return this.Text;
}
set
{
if (value is int)
this.Value = (int)value;
else if (value == null)
this.ValueObject = null;
else
{
string s = Utilities.StripNonNumeric(value.ToString());
double i = 0;
#if FRAMEWORK20
double.TryParse(s, out i);
#else
try
{
i = double.Parse(s);
}
catch { }
#endif
this.Value = i;
}
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter || keyData == Keys.Tab)
{
if (EditComplete != null)
EditComplete(this, new EventArgs());
return true;
}
else if (keyData == Keys.Escape)
{
if (CancelEdit != null)
CancelEdit(this, new EventArgs());
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
public event EventHandler EditComplete;
public event EventHandler CancelEdit;
public bool EditWordWrap
{
get { return false; }
set { }
}
#endregion
}
#endregion
#region Date-Time Custom Editor
internal class DateTimeCellEditor : DateTimeInput, ICellEditControl
{
#region Constructor
/// <summary>
/// Initializes a new instance of the DateTimeCellEditor class.
/// </summary>
public DateTimeCellEditor()
{
this.BackgroundStyle.BorderColor = System.Drawing.Color.Transparent;
}
#endregion
#region ICellEditControl Members
public void BeginEdit()
{
this.MinimumSize = new System.Drawing.Size(70, 10);
}
public void EndEdit()
{
this.Dispose();
}
public object CurrentValue
{
get
{
return this.Text;
}
set
{
if (value is DateTime)
this.Value = (DateTime)value;
else if (value == null)
this.ValueObject = null;
else if(value is string)
{
DateTime date = DateTime.MinValue;
if (DateTime.TryParse((string)value, out date))
this.Value = date;
}
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter || keyData == Keys.Tab)
{
if (EditComplete != null)
EditComplete(this, new EventArgs());
return true;
}
else if (keyData == Keys.Escape)
{
if (CancelEdit != null)
CancelEdit(this, new EventArgs());
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
public event EventHandler EditComplete;
public event EventHandler CancelEdit;
public bool EditWordWrap
{
get { return false; }
set { }
}
#endregion
}
#endregion
#endif
}

View File

@ -0,0 +1,328 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents cell display class.
/// </summary>
internal class CellDisplay
{
public CellDisplay()
{
}
private static Office2007CheckBoxItemPainter _CheckBoxPainter;
public static Office2007CheckBoxItemPainter CheckBoxPainter
{
get { return _CheckBoxPainter; }
set { _CheckBoxPainter = value; }
}
public static Office2007CheckBoxColorTable ColorTable = null;
public static void PaintCell(NodeCellRendererEventArgs ci)
{
if(ci.Cell.CheckBoxVisible)
CellDisplay.PaintCellCheckBox(ci);
if(!ci.Cell.Images.LargestImageSize.IsEmpty)
CellDisplay.PaintCellImage(ci);
CellDisplay.PaintText(ci);
}
public static void PaintCellCheckBox(NodeCellRendererEventArgs ci)
{
if(!ci.Cell.CheckBoxVisible)
return;
Cell cell = ci.Cell;
Rectangle r = cell.CheckBoxBoundsRelative;
r.Offset(ci.CellOffset);
if (ci.CheckBoxImageChecked != null)
{
Image img = ci.CheckBoxImageChecked;
if (cell.CheckState == System.Windows.Forms.CheckState.Unchecked)
img = ci.CheckBoxImageUnChecked;
else if (cell.CheckState == System.Windows.Forms.CheckState.Indeterminate)
img = ci.CheckBoxImageIndeterminate;
if (img != null)
ci.Graphics.DrawImage(img, r);
}
else if (_CheckBoxPainter != null)
{
Office2007CheckBoxStateColorTable ct = GetCheckBoxStateColorTable(ci);
if (cell.CheckBoxStyle == eCheckBoxStyle.CheckBox)
{
_CheckBoxPainter.PaintCheckBox(ci.Graphics, r, ct, cell.CheckState);
}
else
{
_CheckBoxPainter.PaintRadioButton(ci.Graphics, r, ct, cell.Checked);
}
}
else
{
System.Windows.Forms.ButtonState state = System.Windows.Forms.ButtonState.Normal;
if (ci.Cell.Checked)
state = System.Windows.Forms.ButtonState.Checked;
System.Windows.Forms.ControlPaint.DrawCheckBox(ci.Graphics, r, state);
}
}
private static Office2007CheckBoxStateColorTable GetCheckBoxStateColorTable(NodeCellRendererEventArgs e)
{
Cell cell = e.Cell;
if (ColorTable != null && BarFunctions.IsOffice2007Style(e.ColorScheme.Style))
{
Office2007CheckBoxColorTable ct = ColorTable;
if (!cell.GetEnabled())
return ct.Disabled;
//else if (cell.IsMouseDown)
// return ct.Pressed;
//else if (cell.IsMouseOver)
// return ct.MouseOver;
return ct.Default;
}
else
{
ColorScheme cs = e.ColorScheme;
// Create color table based on the ColorScheme object...
Office2007CheckBoxStateColorTable ct = new Office2007CheckBoxStateColorTable();
if (!cell.GetEnabled())
{
ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty);
ct.CheckBorder = cs.ItemDisabledText;
ct.CheckInnerBorder = cs.ItemDisabledText;
ct.CheckInnerBackground = new LinearGradientColorTable();
ct.CheckSign = new LinearGradientColorTable(cs.ItemDisabledText, Color.Empty);
ct.Text = cs.ItemDisabledText;
}
//else if (cell.IsMouseDown)
//{
// ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty);
// ct.CheckBorder = cs.ItemPressedBorder;
// ct.CheckInnerBorder = cs.ItemPressedBorder;
// ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemPressedBackground, cs.ItemPressedBackground2);
// ct.CheckSign = new LinearGradientColorTable(cs.ItemPressedText, Color.Empty);
// ct.Text = cs.ItemPressedText;
//}
//else if (cell.IsMouseOver)
//{
// ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty);
// ct.CheckBorder = cs.ItemHotBorder;
// ct.CheckInnerBorder = cs.ItemHotBorder;
// ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemHotBackground, cs.ItemHotBackground2);
// ct.CheckSign = new LinearGradientColorTable(cs.ItemHotText, Color.Empty);
// ct.Text = cs.ItemHotText;
//}
else
{
ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty);
ct.CheckBorder = cs.PanelBorder;
ct.CheckInnerBorder = ColorBlendFactory.SoftLight(cs.PanelBorder, Color.White);
ct.CheckInnerBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty);
ct.CheckSign = new LinearGradientColorTable(cs.ItemText, Color.Empty);
ct.Text = cs.ItemText;
}
return ct;
}
}
public static void PaintCellImage(NodeCellRendererEventArgs ci)
{
if(ci.Cell.Images.LargestImageSize.IsEmpty)
return;
Rectangle r=ci.Cell.ImageBoundsRelative;
r.Offset(ci.CellOffset);
Image image = CellDisplay.GetCellImage(ci.Cell);
if(image!=null)
{
Size imageSize = Dpi.ImageSize(image.Size);
ci.Graphics.DrawImage(image, r.X + (r.Width - imageSize.Width) / 2,
r.Y + (r.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height);
}
}
public static void PaintText(NodeCellRendererEventArgs ci)
{
Cell cell = ci.Cell;
if (cell.HostedControl == null && cell.HostedItem == null && (cell.DisplayText == "" || ci.Style.TextColor.IsEmpty) || cell.TextContentBounds.IsEmpty)
return;
Rectangle bounds = ci.Cell.TextContentBounds;
bounds.Offset(ci.CellOffset);
Graphics g = ci.Graphics;
if (cell.HostedControl != null)
{
if (!cell.HostedControl.Visible)
cell.HostedControl.Visible = true;
return;
}
else if (cell.HostedItem != null)
{
BaseItem item = cell.HostedItem;
if (item.ItemAlignment == eItemAlignment.Near)
item.LeftInternal = bounds.X;
else if (item.ItemAlignment == eItemAlignment.Far)
item.LeftInternal = bounds.X + (bounds.Width - item.WidthInternal);
else if (item.ItemAlignment == eItemAlignment.Center)
item.LeftInternal = bounds.X + (bounds.Width - item.WidthInternal) / 2;
if (item.DisplayRectangle.Height < bounds.Height)
item.TopInternal = bounds.Y + (bounds.Height - item.DisplayRectangle.Height) / 2;
else
item.TopInternal = bounds.Y;
item.Displayed = true;
Region oldClip = g.Clip;
Rectangle cb = bounds;
cb.Inflate(2, 1);
g.SetClip(cb, CombineMode.Intersect);
item.Paint(ci.ItemPaintArgs);
if (oldClip != null)
{
g.Clip = oldClip;
oldClip.Dispose();
}
return;
}
Font font = ci.Style.Font;
if (bounds.Width > 1 && bounds.Height > 1)
{
//eTextFormat textFormat = ci.Style.TextFormat;
//textFormat = textFormat & ~(textFormat & eTextFormat.HidePrefix);
//textFormat |= eTextFormat.NoPrefix;
if (cell.TextMarkupBody == null)
{
TextDrawing.DrawString(g, cell.DisplayText, font, ci.Style.TextColor, bounds, ci.Style.TextFormat);
}
else
{
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(g, font, ci.Style.TextColor, false);
d.HotKeyPrefixVisible = !((ci.Style.TextFormat & eTextFormat.HidePrefix) == eTextFormat.HidePrefix);
Rectangle mr = Rectangle.Empty;
eStyleTextAlignment lineAlignment = ci.Style.TextLineAlignment;
if (lineAlignment == eStyleTextAlignment.Center)
{
mr = new Rectangle(bounds.X, bounds.Y + (bounds.Height - cell.TextMarkupBody.Bounds.Height) / 2, cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height);
}
else if (lineAlignment == eStyleTextAlignment.Near)
{
mr = new Rectangle(bounds.X, bounds.Y, cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height);
}
else // Far
{
mr = new Rectangle(bounds.X, bounds.Y + (bounds.Height - cell.TextMarkupBody.Bounds.Height), cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height);
}
cell.TextMarkupBody.Bounds = mr;
cell.TextMarkupBody.Render(d);
}
}
}
private static Image GetCellImage(Cell cell)
{
Image img=cell.Images.Image;
bool enabled = cell.GetEnabled();
if (!enabled && (cell.Images.ImageDisabled != null || cell.Images.ImageDisabledIndex >= 0 || cell.Images.DisabledImageGenerated != null))
{
if (cell.Images.DisabledImageGenerated != null) return cell.Images.DisabledImageGenerated;
if (cell.Images.ImageDisabled != null) return cell.Images.ImageDisabled;
if (cell.Images.ImageDisabledIndex >= 0) return cell.Images.GetImageByIndex(cell.Images.ImageDisabledIndex);
}
if(img == null && !string.IsNullOrEmpty(cell.Images.ImageKey))
img = cell.Images.GetImageByKey(cell.Images.ImageKey);
if (img == null && cell.Images.ImageIndex >= 0)
img = cell.Images.GetImageByIndex(cell.Images.ImageIndex);
if (!enabled && img is Bitmap)
{
cell.Images.DisposeGeneratedDisabledImage();
cell.Images.DisabledImageGenerated = ImageHelper.CreateGrayScaleImage(img as Bitmap);
if (cell.Images.DisabledImageGenerated != null) return cell.Images.DisabledImageGenerated;
return img;
}
if(cell.IsMouseOver && (cell.Images.ImageMouseOver!=null || cell.Images.ImageMouseOverIndex>= 0 || !string.IsNullOrEmpty(cell.Images.ImageMouseOverKey)))
{
if (cell.Images.ImageMouseOver != null)
img = cell.Images.ImageMouseOver;
else if (cell.Images.ImageMouseOverIndex >= 0)
img = cell.Images.GetImageByIndex(cell.Images.ImageMouseOverIndex);
else
img = cell.Images.GetImageByKey(cell.Images.ImageMouseOverKey);
}
else if(cell.Parent.Expanded && (cell.Images.ImageExpanded!=null || cell.Images.ImageExpandedIndex>= 0 || !string.IsNullOrEmpty(cell.Images.ImageExpandedKey)))
{
if (cell.Images.ImageExpanded != null)
img = cell.Images.ImageExpanded;
else if (cell.Images.ImageExpandedIndex >= 0)
img = cell.Images.GetImageByIndex(cell.Images.ImageExpandedIndex);
else
img = cell.Images.GetImageByKey(cell.Images.ImageExpandedKey);
}
return img;
}
public static Font GetCellFont(AdvTree tree, Cell cell)
{
Font font=tree.Font;
ElementStyle style=null;
if(cell.StyleNormal!=null)
{
style=cell.StyleNormal;
}
else
{
if(tree.NodeStyle!=null)
style=tree.NodeStyle;
else
style=new ElementStyle();
if(tree.CellStyleDefault!=null)
style=tree.CellStyleDefault;
else
style=ElementStyle.GetDefaultCellStyle(style);
}
if(style!=null && style.Font!=null)
font=style.Font;
return font;
}
}
/// <summary>
/// Represents information necessary to paint the cell on canvas.
/// </summary>
internal class CellDisplayInfo
{
public ElementStyle Style=null;
public System.Drawing.Graphics Graphics=null;
public Cell ContextCell=null;
public Point CellOffset=Point.Empty;
public CellDisplayInfo()
{
}
public CellDisplayInfo(ElementStyle style, System.Drawing.Graphics g, Cell cell, Point cellOffset)
{
this.Style=style;
this.Graphics=g;
this.ContextCell=cell;
this.CellOffset=cellOffset;
}
}
}

View File

@ -0,0 +1,384 @@
using System;
using System.Text;
using DevComponents.WinForms.Drawing;
using System.Drawing;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Initializes the tree color tables.
/// </summary>
internal class ColorTableInitializer
{
#region Office 2007 Blue
public static void InitOffice2007Blue(TreeColorTable ct, ColorFactory factory)
{
#region Tree Selection
TreeSelectionColors treeSelection = new TreeSelectionColors();
ct.Selection = treeSelection;
// Highlight full row
SelectionColorTable selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0));
treeSelection.FullRowSelect = selColorTable;
// Highlight full row Inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5));
treeSelection.FullRowSelectInactive = selColorTable;
// Node Marker
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1);
treeSelection.NodeMarker = selColorTable;
// Node marker inactibe
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1);
treeSelection.NodeMarkerInactive = selColorTable;
// Cell selection
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(new ColorStop[] {
new ColorStop(factory.GetColor(0xFFFCD9), 0f),
new ColorStop(factory.GetColor(0xFFE78D), .4f),
new ColorStop(factory.GetColor(0xFFD748), .4f),
new ColorStop(factory.GetColor(0xFFE793), 1f)
});
selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1);
//selColorTable = new SelectionColorTable();
//selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90);
//selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1);
//selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1);
treeSelection.HighlightCells = selColorTable;
// Cell selection inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.HighlightCellsInactive = selColorTable;
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.NodeHotTracking = selColorTable;
#endregion
#region Expand Buttons
TreeExpandColorTable expand = new TreeExpandColorTable();
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1);
expand.CollapseFill = new SolidFill(factory.GetColor(0x595959));
expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB));
expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1);
expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF));
expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA));
ct.ExpandTriangle = expand;
// Rectangle
expand = new TreeExpandColorTable();
expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000));
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1);
expand.CollapseFill = new GradientFill(new ColorStop[]{
new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45);
expand.CollapseMouseOverForeground = expand.CollapseForeground;
expand.CollapseMouseOverBorder = expand.CollapseBorder;
expand.CollapseMouseOverFill = expand.CollapseFill;
expand.ExpandForeground = expand.CollapseForeground;
expand.ExpandBorder = expand.CollapseBorder;
expand.ExpandFill = expand.CollapseFill;
expand.ExpandMouseOverForeground = expand.CollapseForeground;
expand.ExpandMouseOverBorder = expand.CollapseBorder;
expand.ExpandMouseOverFill = expand.CollapseFill;
ct.ExpandRectangle = expand;
ct.ExpandEllipse = expand;
#endregion
#region Misc Tree Color
ct.GridLines = factory.GetColor(0xE1E1E1);
#endregion
}
#endregion
#region Office 2007 Silver
public static void InitOffice2007Silver(TreeColorTable ct, ColorFactory factory)
{
#region Tree Selection
TreeSelectionColors treeSelection = new TreeSelectionColors();
ct.Selection = treeSelection;
// Highlight full row
SelectionColorTable selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0));
treeSelection.FullRowSelect = selColorTable;
// Highlight full row Inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5));
treeSelection.FullRowSelectInactive = selColorTable;
// Node Marker
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1);
treeSelection.NodeMarker = selColorTable;
// Node marker inactibe
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1);
treeSelection.NodeMarkerInactive = selColorTable;
// Cell selection
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(new ColorStop[] {
new ColorStop(factory.GetColor(0xFFFCD9), 0f),
new ColorStop(factory.GetColor(0xFFE78D), .4f),
new ColorStop(factory.GetColor(0xFFD748), .4f),
new ColorStop(factory.GetColor(0xFFE793), 1f)
});
selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1);
//selColorTable = new SelectionColorTable();
//selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90);
//selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1);
//selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1);
treeSelection.HighlightCells = selColorTable;
// Cell selection inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.HighlightCellsInactive = selColorTable;
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.NodeHotTracking = selColorTable;
#endregion
#region Expand Buttons
TreeExpandColorTable expand = new TreeExpandColorTable();
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1);
expand.CollapseFill = new SolidFill(factory.GetColor(0x595959));
expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB));
expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1);
expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF));
expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA));
ct.ExpandTriangle = expand;
// Rectangle
expand = new TreeExpandColorTable();
expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000));
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1);
expand.CollapseFill = new GradientFill(new ColorStop[]{
new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45);
expand.CollapseMouseOverForeground = expand.CollapseForeground;
expand.CollapseMouseOverBorder = expand.CollapseBorder;
expand.CollapseMouseOverFill = expand.CollapseFill;
expand.ExpandForeground = expand.CollapseForeground;
expand.ExpandBorder = expand.CollapseBorder;
expand.ExpandFill = expand.CollapseFill;
expand.ExpandMouseOverForeground = expand.CollapseForeground;
expand.ExpandMouseOverBorder = expand.CollapseBorder;
expand.ExpandMouseOverFill = expand.CollapseFill;
ct.ExpandRectangle = expand;
ct.ExpandEllipse = expand;
#endregion
#region Misc Tree Color
ct.GridLines = factory.GetColor(0xE1E1E1);
#endregion
}
#endregion
#region Office 2007 Black
public static void InitOffice2007Black(TreeColorTable ct, ColorFactory factory)
{
#region Tree Selection
TreeSelectionColors treeSelection = new TreeSelectionColors();
ct.Selection = treeSelection;
// Highlight full row
SelectionColorTable selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0));
treeSelection.FullRowSelect = selColorTable;
// Highlight full row Inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5));
treeSelection.FullRowSelectInactive = selColorTable;
// Node Marker
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1);
treeSelection.NodeMarker = selColorTable;
// Node marker inactibe
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1);
treeSelection.NodeMarkerInactive = selColorTable;
// Cell selection
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(new ColorStop[] {
new ColorStop(factory.GetColor(0xFFFCD9), 0f),
new ColorStop(factory.GetColor(0xFFE78D), .4f),
new ColorStop(factory.GetColor(0xFFD748), .4f),
new ColorStop(factory.GetColor(0xFFE793), 1f)
});
selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1);
//selColorTable = new SelectionColorTable();
//selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90);
//selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1);
//selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1);
treeSelection.HighlightCells = selColorTable;
// Cell selection inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.HighlightCellsInactive = selColorTable;
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1);
treeSelection.NodeHotTracking = selColorTable;
#endregion
#region Expand Buttons
TreeExpandColorTable expand = new TreeExpandColorTable();
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1);
expand.CollapseFill = new SolidFill(factory.GetColor(0x595959));
expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB));
expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1);
expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF));
expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA));
ct.ExpandTriangle = expand;
// Rectangle
expand = new TreeExpandColorTable();
expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000));
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1);
expand.CollapseFill = new GradientFill(new ColorStop[]{
new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45);
expand.CollapseMouseOverForeground = expand.CollapseForeground;
expand.CollapseMouseOverBorder = expand.CollapseBorder;
expand.CollapseMouseOverFill = expand.CollapseFill;
expand.ExpandForeground = expand.CollapseForeground;
expand.ExpandBorder = expand.CollapseBorder;
expand.ExpandFill = expand.CollapseFill;
expand.ExpandMouseOverForeground = expand.CollapseForeground;
expand.ExpandMouseOverBorder = expand.CollapseBorder;
expand.ExpandMouseOverFill = expand.CollapseFill;
ct.ExpandRectangle = expand;
ct.ExpandEllipse = expand;
#endregion
#region Misc Tree Color
ct.GridLines = factory.GetColor(0xE1E1E1);
#endregion
}
#endregion
#region Office 2007 Vista Glass
public static void InitOffice2007VistaGlass(TreeColorTable ct, ColorFactory factory)
{
#region Tree Selection
TreeSelectionColors treeSelection = new TreeSelectionColors();
ct.Selection = treeSelection;
// Highlight full row
SelectionColorTable selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xC4E8FA));
treeSelection.FullRowSelect = selColorTable;
// Highlight full row Inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5));
treeSelection.FullRowSelectInactive = selColorTable;
// Node Marker
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1);
treeSelection.NodeMarker = selColorTable;
// Node marker inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5));
selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1);
treeSelection.NodeMarkerInactive = selColorTable;
// Cell selection
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(new ColorStop[] {
new ColorStop(factory.GetColor(0xF1F8FD), 0f),
new ColorStop(factory.GetColor(0xD5EFFC), 1f)
});
selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xF6FBFD), 1);
//selColorTable = new SelectionColorTable();
//selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90);
//selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1);
//selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1);
treeSelection.HighlightCells = selColorTable;
// Cell selection inactive
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xF8F8F8), factory.GetColor(0xE5E5E5), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1);
selColorTable.BorderCornerRadius = 2;
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFAFAFB), 1);
treeSelection.HighlightCellsInactive = selColorTable;
selColorTable = new SelectionColorTable();
selColorTable.Fill = new GradientFill(factory.GetColor(0xF5FAFD), factory.GetColor(0xE8F5FD), 90);
selColorTable.Border = new SolidBorder(factory.GetColor(0xD8F0FA), 1);
selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xF8FCFE), 1);
treeSelection.NodeHotTracking = selColorTable;
#endregion
#region Expand Buttons
TreeExpandColorTable expand = new TreeExpandColorTable();
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1);
expand.CollapseFill = new SolidFill(factory.GetColor(0x595959));
expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB));
expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1);
expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF));
expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1);
expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA));
ct.ExpandTriangle = expand;
// Rectangle
expand = new TreeExpandColorTable();
expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000));
expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1);
expand.CollapseFill = new GradientFill(new ColorStop[]{
new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45);
expand.CollapseMouseOverForeground = expand.CollapseForeground;
expand.CollapseMouseOverBorder = expand.CollapseBorder;
expand.CollapseMouseOverFill = expand.CollapseFill;
expand.ExpandForeground = expand.CollapseForeground;
expand.ExpandBorder = expand.CollapseBorder;
expand.ExpandFill = expand.CollapseFill;
expand.ExpandMouseOverForeground = expand.CollapseForeground;
expand.ExpandMouseOverBorder = expand.CollapseBorder;
expand.ExpandMouseOverFill = expand.CollapseFill;
ct.ExpandRectangle = expand;
ct.ExpandEllipse = expand;
#endregion
#region Misc Tree Color
ct.GridLines = factory.GetColor(0xEDEDED);
#endregion
}
#endregion
}
}

View File

@ -0,0 +1,119 @@
using System;
using System.Text;
using DevComponents.DotNetBar;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.AdvTree.Display
{
internal class ColumnHeaderDisplay
{
internal void DrawColumnHeader(ColumnHeaderRendererEventArgs e, ElementStyleDisplayInfo di)
{
// Adjust the header bounds so the header is filled completely
if (e.Tree != null && e.Tree.CellHorizontalSpacing > 0 && !e.ColumnHeader.IsFirstVisible) {
Rectangle ob = di.Bounds;
di.Bounds = new Rectangle(ob.X - e.Tree.CellHorizontalSpacing, ob.Y, ob.Width + e.Tree.CellHorizontalSpacing, ob.Height);
ElementStyleDisplay.Paint(di);
di.Bounds = ob;
}
else
ElementStyleDisplay.Paint(di);
di.Bounds.Inflate(-1, -1);
if (di.Bounds.Width > 1 && di.Bounds.Height > 1)
{
if (e.ColumnHeader.IsFirstVisible)
{
Rectangle r = di.Bounds;
r.Width -= 3;
r.X += 3;
di.Bounds = r;
}
if (e.ColumnHeader.SortDirection != eSortDirection.None && !e.SortIndicatorColor.IsEmpty)
{
using (GraphicsPath sortShapePath = UIGraphics.GetTrianglePath(
new Point(di.Bounds.Right - 11, di.Bounds.Y + (di.Bounds.Height - 5) / 2), 9,
(e.ColumnHeader.SortDirection == eSortDirection.Ascending ? eTriangleDirection.Top : eTriangleDirection.Bottom)))
{
SmoothingMode sm = e.Graphics.SmoothingMode;
e.Graphics.SmoothingMode = SmoothingMode.Default;
using (SolidBrush brush = new SolidBrush(e.SortIndicatorColor))
e.Graphics.FillPath(brush, sortShapePath);
e.Graphics.SmoothingMode = sm;
}
di.Bounds.Width -= 12;
}
if (e.ColumnHeader.Image != null)
{
Image image = e.ColumnHeader.Image;
Rectangle r = di.Bounds;
if (e.ColumnHeader.ImageAlignment == eColumnImageAlignment.Left)
{
e.Graphics.DrawImage(image, r.X,
r.Y + (r.Height - image.Height) / 2, image.Width, image.Height);
r.X += image.Width + 2;
r.Width -= image.Width + 2;
}
else if (e.ColumnHeader.ImageAlignment == eColumnImageAlignment.Right)
{
e.Graphics.DrawImage(image, r.Right - image.Width,
r.Y + (r.Height - image.Height) / 2, image.Width, image.Height);
r.Width -= image.Width + 2;
}
di.Bounds = r;
}
ElementStyleDisplay.PaintText(di, e.ColumnHeader.Text, e.Tree.Font);
}
}
internal static void PaintColumnMoveMarker(Graphics g, AdvTree tree, int columnMoveMarkerIndex, ColumnHeaderCollection columns)
{
if (columnMoveMarkerIndex == -1) throw new ArgumentException("columnMoveMarkerIndex must be grater or equal than 0");
if (columns == null) throw new ArgumentNullException("columns");
Color lineColor = ColorScheme.GetColor("834DD5");
Color fillColor = ColorScheme.GetColor("CCCFF8");
Size markerSize = new Size(10, 14);
ColumnHeader header = null;
if (columnMoveMarkerIndex == columns.Count)
header = columns.LastVisibleColumn;
else
header = columns[columnMoveMarkerIndex];
Rectangle markerBounds = Rectangle.Empty;
if (columnMoveMarkerIndex == columns.Count)
markerBounds = new Rectangle(header.Bounds.Right - markerSize.Width, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height);
else if (columns[columnMoveMarkerIndex] == columns.FirstVisibleColumn)
markerBounds = new Rectangle(header.Bounds.X, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height);
else
markerBounds = new Rectangle(header.Bounds.X - markerSize.Width / 2 - tree.NodeLayout.GetCellLayout().LayoutSettings.CellHorizontalSpacing, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height);
if (tree.AutoScrollPosition.X != 0)
markerBounds.Offset(tree.AutoScrollPosition.X, 0);
using (GraphicsPath path = CreateMarker(markerBounds))
{
using (SolidBrush brush = new SolidBrush(fillColor))
g.FillPath(brush, path);
using (Pen pen = new Pen(lineColor, 1))
g.DrawPath(pen, path);
}
}
private static GraphicsPath CreateMarker(Rectangle markerBounds)
{
markerBounds.Height--;
GraphicsPath path = new GraphicsPath();
path.AddLine(markerBounds.X + markerBounds.Width / 2, markerBounds.Bottom, markerBounds.X, markerBounds.Bottom - markerBounds.Width / 2);
path.AddLine(markerBounds.X, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.X + markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2);
path.AddLine(markerBounds.X + markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.X + markerBounds.Width / 3, markerBounds.Y);
path.AddLine(markerBounds.X + markerBounds.Width / 3, markerBounds.Y, markerBounds.Right - markerBounds.Width / 3, markerBounds.Y);
path.AddLine(markerBounds.Right - markerBounds.Width / 3, markerBounds.Y, markerBounds.Right - markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2);
path.AddLine(markerBounds.Right - markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.Right, markerBounds.Bottom - markerBounds.Width / 2);
path.CloseAllFigures();
return path;
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Text;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Provides data for RenderColumnHeader event.
/// </summary>
public class ColumnHeaderRendererEventArgs : EventArgs
{
/// <summary>
/// Gets the column header that is rendered.
/// </summary>
public ColumnHeader ColumnHeader = null;
/// <summary>
/// Target Graphics canvas.
/// </summary>
public Graphics Graphics;
/// <summary>
/// Gets the bounds of the column header.
/// </summary>
public Rectangle Bounds;
/// <summary>
/// Gets the effective style for the column.
/// </summary>
public ElementStyle Style = null;
/// <summary>
/// Gets the AdvTree control header is rendered for.
/// </summary>
public AdvTree Tree = null;
/// <summary>
/// Gets or sets the color of the column sort indicator.
/// </summary>
public Color SortIndicatorColor = Color.Empty;
/// <summary>
/// Initializes a new instance of the ColumnHeaderRendererEventArgs class.
/// </summary>
public ColumnHeaderRendererEventArgs()
{
}
/// <summary>
/// Initializes a new instance of the ColumnHeaderRendererEventArgs class.
/// </summary>
/// <param name="columnHeader"></param>
/// <param name="graphics"></param>
/// <param name="bounds"></param>
/// <param name="style"></param>
public ColumnHeaderRendererEventArgs(AdvTree tree, ColumnHeader columnHeader, Graphics graphics, Rectangle bounds, ElementStyle style)
{
Tree = tree;
ColumnHeader = columnHeader;
Graphics = graphics;
Bounds = bounds;
Style = style;
}
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents helper class for node connector display.
/// </summary>
public class ConnectorRendererEventArgs:EventArgs
{
/// <summary>
/// From node reference.
/// </summary>
public Node FromNode=null;
/// <summary>
/// From node style reference.
/// </summary>
public ElementStyle StyleFromNode=null;
/// <summary>
/// To node reference.
/// </summary>
public Node ToNode=null;
/// <summary>
/// To node style reference.
/// </summary>
public ElementStyle StyleToNode=null;
/// <summary>
/// Graphics object used for drawing.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Node offset since some node coordinates are relative.
/// </summary>
public Point Offset=Point.Empty;
/// <summary>
/// Indicates whether from node is a root node.
/// </summary>
public bool IsRootNode=false;
/// <summary>
/// Reference to node connector object that describes connector type.
/// </summary>
public NodeConnector NodeConnector=null;
/// <summary>
/// Gets or sets whether connector is link connector.
/// </summary>
public bool LinkConnector=false;
/// <summary>
/// Reference to the collection of the connector path points. Default value is null indicating there are no path points.
/// </summary>
public ConnectorPointsCollection ConnectorPoints=null;
}
}

View File

@ -0,0 +1,78 @@
using System;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.AdvTree.Display
{
internal class DragDropMarkerDisplay
{
public void DrawMarker(DragDropMarkerRendererEventArgs e)
{
Graphics g = e.Graphics;
Rectangle bounds = e.Bounds;
if (bounds.IsEmpty || _MarkerColor.IsEmpty) return;
if (bounds.Width == AdvTree.DragInsertMarkSize) // Vertical insert mark
{
using (SolidBrush brush = new SolidBrush(_MarkerColor))
{
using (Pen pen = new Pen(brush, 1))
{
Point p = new Point(bounds.X + 4, bounds.Y);
g.DrawLine(pen, p.X, p.Y, p.X, bounds.Bottom - 1);
}
using (GraphicsPath path = new GraphicsPath())
{
path.AddLine(bounds.X, bounds.Y, bounds.X + 8, bounds.Y );
path.AddLine(bounds.X + 8, bounds.Y, bounds.X + 4, bounds.Y + 4);
path.CloseAllFigures();
g.FillPath(brush, path);
}
using (GraphicsPath path = new GraphicsPath())
{
path.AddLine(bounds.X, bounds.Bottom, bounds.X + 8, bounds.Bottom);
path.AddLine(bounds.X + 8, bounds.Bottom, bounds.X + 4, bounds.Bottom - 4);
path.CloseAllFigures();
g.FillPath(brush, path);
}
}
}
else
{
// Horizontal insert mark
using (SolidBrush brush = new SolidBrush(_MarkerColor))
{
using (Pen pen = new Pen(brush, 1))
{
Point p = new Point(bounds.X, bounds.Y + 4);
g.DrawLine(pen, p.X, p.Y, bounds.Right - 1, p.Y);
}
using (GraphicsPath path = new GraphicsPath())
{
path.AddLine(bounds.X, bounds.Y, bounds.X, bounds.Y + 8);
path.AddLine(bounds.X, bounds.Y + 8, bounds.X + 4, bounds.Y + 4);
path.CloseAllFigures();
g.FillPath(brush, path);
}
using (GraphicsPath path = new GraphicsPath())
{
path.AddLine(bounds.Right, bounds.Y, bounds.Right, bounds.Y + 8);
path.AddLine(bounds.Right, bounds.Y + 8, bounds.Right - 4, bounds.Y + 4);
path.CloseAllFigures();
g.FillPath(brush, path);
}
}
}
}
private Color _MarkerColor;
public Color MarkerColor
{
get { return _MarkerColor; }
set { _MarkerColor = value; }
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Text;
using System.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Provides data for the NodeRenderer.RenderDragDropMarker event.
/// </summary>
public class DragDropMarkerRendererEventArgs : EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics = null;
/// <summary>
/// Gets or sets the selection bounds.
/// </summary>
public Rectangle Bounds = Rectangle.Empty;
/// <summary>
/// Initializes a new instance of the DragDropMarkerRendererEventArgs class.
/// </summary>
public DragDropMarkerRendererEventArgs()
{
}
/// <summary>
/// Initializes a new instance of the DragDropMarkerRendererEventArgs class.
/// </summary>
/// <param name="graphics"></param>
/// <param name="bounds"></param>
public DragDropMarkerRendererEventArgs(System.Drawing.Graphics graphics, Rectangle bounds)
{
Graphics = graphics;
Bounds = bounds;
}
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.AdvTree.Display;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents the line connector display class.
/// </summary>
public class LineConnectorDisplay:NodeConnectorDisplay
{
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public override void DrawConnector(ConnectorRendererEventArgs info)
{
if(info.NodeConnector.LineColor.IsEmpty || info.NodeConnector.LineWidth<=0)
return;
Point pStart, pEnd;
// FromNode is null when connector is rendered for the child node
if (info.FromNode == null)
{
Rectangle cellBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, info.ToNode, info.Offset);
Rectangle expandBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, info.ToNode, info.Offset);
pStart = new Point(cellBounds.X - 4, cellBounds.Y + cellBounds.Height / 2);
pEnd = new Point(expandBounds.X + expandBounds.Width / 2, pStart.Y);
}
else
{
// FromNode is parent node, ToNode is last visible child node. Connector is vertical line from parent to last visible child
Rectangle cellBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, info.FromNode, info.Offset);
Rectangle expandBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, info.ToNode, info.Offset);
pStart = new Point(expandBounds.X + expandBounds.Width / 2, cellBounds.Bottom);
pEnd = new Point(pStart.X, expandBounds.Y + expandBounds.Height / 2);
}
Graphics g = info.Graphics;
using (Pen pen = GetLinePen(info))
{
SmoothingMode sm = g.SmoothingMode;
if (pen.DashStyle != DashStyle.Solid)
g.SmoothingMode = SmoothingMode.Default;
g.DrawLine(pen, pStart, pEnd);
g.SmoothingMode = sm;
}
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Provides information for cell rendering methods and events.
/// </summary>
public class NodeCellRendererEventArgs:NodeRendererEventArgs
{
/// <summary>
/// Gets or sets the cell being rendered.
/// </summary>
public Cell Cell=null;
/// <summary>
/// Gets or sets absolute cell bounds.
/// </summary>
public Rectangle CellBounds=Rectangle.Empty;
/// <summary>
/// Gets or sets the internal cell offset.
/// </summary>
internal Point CellOffset=Point.Empty;
/// <summary>
/// Gets or sets the color scheme.
/// </summary>
internal ColorScheme ColorScheme = null;
internal Image CheckBoxImageChecked = null;
internal Image CheckBoxImageUnChecked = null;
internal Image CheckBoxImageIndeterminate = null;
internal ItemPaintArgs ItemPaintArgs = null;
/// <summary>
/// Creates new instance of the class.
/// </summary>
public NodeCellRendererEventArgs():base(null,null,Rectangle.Empty,null)
{
}
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
/// <param name="node">Reference to context node.</param>
/// <param name="bounds">Reference to node bounds</param>
/// <param name="style">Reference to cell style</param>
/// <param name="cell">Reference to cell</param>
/// <param name="cellBounds">Reference to cell bounds</param>
public NodeCellRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style, Cell cell, Rectangle cellBounds):base(g,node,bounds,style)
{
this.Cell = cell;
this.CellBounds = cellBounds;
}
}
}

View File

@ -0,0 +1,511 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.AdvTree
{
namespace Display
{
/// <summary>
/// Base class for drawing node connectors.
/// </summary>
public abstract class NodeConnectorDisplay
{
//private bool m_RootNode=false;
//private bool m_DrawRootAllLevels=false;
//private bool m_EndCap=true;
//private bool m_DrawConnectorUnderNodes=true;
/// <summary>
/// Creates new instance of the object.
/// </summary>
public NodeConnectorDisplay()
{
}
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public virtual void DrawConnector(ConnectorRendererEventArgs info){}
///// <summary>
///// Returns the connector starting coordinates.
///// </summary>
///// <param name="info">Connector display information.</param>
///// <returns>Point object.</returns>
//protected virtual Point GetStartPoint(ConnectorRendererEventArgs info)
//{
// Point p=Point.Empty;
// if(info.IsRootNode)
// {
// //int toMidPoint=info.ToNode.Bounds.Top+info.ToNode.Bounds.Height/2;
// //if(info.FromNode.Bounds.Top>toMidPoint)
// if(IsAbove(info.FromNode,info.ToNode))
// p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Top);
// //else if(info.FromNode.Bounds.Bottom<toMidPoint)
// else if(IsBelow(info.FromNode,info.ToNode))
// p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Bottom-1);
// }
// if(p.IsEmpty)
// {
// // To element to the Left
// if(this.IsOnLeftSide(info.FromNode,info.ToNode))
// p=new Point(info.FromNode.BoundsRelative.Left,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
// else
// {
// p=new Point(info.FromNode.BoundsRelative.Right,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
// if(info.IsRootNode)
// p.X--;
// if(!NodeDisplay.DrawExpandPart(info.FromNode) && info.FromNode.ExpandVisibility==eNodeExpandVisibility.Auto)
// p.X-=(info.FromNode.BoundsRelative.Width-info.FromNode.ContentBounds.Width);
// }
// }
// if(!p.IsEmpty)
// p.Offset(info.Offset.X,info.Offset.Y);
// return p;
//}
///// <summary>
///// Returns true if fromNode is above the toNode.
///// </summary>
///// <param name="fromNode">From Node object.</param>
///// <param name="toNode">To Node object</param>
///// <returns>True if fromNode is above toNode.</returns>
//protected bool IsAbove(Node fromNode, Node toNode)
//{
// //int toMidPoint=toNode.Bounds.Top+toNode.Bounds.Height/2;
// //if(fromNode.Bounds.Top>toMidPoint)
// if(fromNode.BoundsRelative.Top>toNode.BoundsRelative.Bottom)
// return true;
// return false;
//}
///// <summary>
///// Returns true if fromNode is below toNode.
///// </summary>
///// <param name="fromNode">From Node object.</param>
///// <param name="toNode">To Node object.</param>
///// <returns>True if fromNode is below toNode.</returns>
//protected bool IsBelow(Node fromNode, Node toNode)
//{
// int toMidPoint=toNode.BoundsRelative.Top+toNode.BoundsRelative.Height/2;
// if(fromNode.BoundsRelative.Bottom<toMidPoint)
// return true;
// return false;
//}
///// <summary>
///// Returns whether connector is extended to underline the node.
///// </summary>
///// <param name="nodeStyle">Refernce to Node style.</param>
///// <returns>True if node should be underlined by connector.</returns>
//protected bool UnderlineNode(ElementStyle nodeStyle)
//{
// if(!nodeStyle.PaintBottomBorder && !nodeStyle.PaintTopBorder &&
// !nodeStyle.PaintLeftBorder && !nodeStyle.PaintRightBorder)
// return true;
// return false;
//}
///// <summary>
///// Returns the connector end point. The array of end points. Two valid points will be returned if node needs to be underlined by connector.
///// </summary>
///// <param name="info">Connector display info.</param>
///// <returns>Array of point objects.</returns>
//protected Point[] GetEndPoint(ConnectorRendererEventArgs info)
//{
// // If to element is to the right of the from node and has left border end point is the vertical mid-point
// // If to element is to the left of the from node and has right border end point is the vertical mid-point
// // If there is no border end point is text bottom
// // If this is link connector the end point is the middle bottom or top point of the node
// Point p=Point.Empty;
// Point pLineEnd=Point.Empty;
// int capWidthOffset = 0; // GetCapWidthOffset(info.NodeConnector.EndCap, info.NodeConnector.EndCapSize);
// bool leftSide=this.IsOnLeftSide(info.FromNode,info.ToNode);
// if(info.LinkConnector && info.FromNode.BoundsRelative.Top>info.ToNode.BoundsRelative.Bottom)
// p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Bottom+1);
// else if(info.LinkConnector && info.FromNode.BoundsRelative.Bottom<info.ToNode.BoundsRelative.Top)
// p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Top-info.NodeConnector.EndCapSize.Height);
// else
// {
// if(leftSide)
// {
// // To element is to the left of from node
// Rectangle r=info.ToNode.BoundsRelative;
// if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
// {
// p=new Point(r.Right,r.Bottom);
// if(m_EndCap)
// p.X+=capWidthOffset;
// if(info.NodeConnector.UnderlineNoBorderNode)
// {
// Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
// pLineEnd=new Point(rc.Left+1,r.Bottom);
// }
// }
// else
// {
// p=new Point(r.Right,r.Y+r.Height/2);
// if(m_EndCap)
// p.X+=capWidthOffset;
// }
// }
// else
// {
// // To element to the right of from node
// Rectangle r=info.ToNode.BoundsRelative;
// if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
// {
// //r=NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds,info.ToNode.Cells[0],Point.Empty);
// //r=info.ToNode.Cells[0].TextContentBounds;
// p=new Point(r.X,r.Bottom);
// if(m_EndCap)
// p.X-=capWidthOffset;
// if(info.NodeConnector.UnderlineNoBorderNode)
// {
// Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
// pLineEnd=new Point(rc.Right-1,r.Bottom);
// }
// }
// else
// {
// p=new Point(r.X,r.Y+r.Height/2);
// if(m_EndCap)
// p.X-=capWidthOffset;
// }
// }
// }
// if(!p.IsEmpty)
// p.Offset(info.Offset.X,info.Offset.Y);
// if(!pLineEnd.IsEmpty)
// pLineEnd.Offset(info.Offset.X,info.Offset.Y);
// return new Point[] {p,pLineEnd};
//}
///// <summary>
///// Returns the offest for the node connector cap.
///// </summary>
///// <param name="cap">Cap type.</param>
///// <param name="size">Cap size.</param>
///// <returns></returns>
//protected int GetCapWidthOffset(eConnectorCap cap,Size size)
//{
// int capWidthOffset=0;
// switch(cap)
// {
// case eConnectorCap.Arrow:
// capWidthOffset=size.Width+1;
// break;
// case eConnectorCap.Ellipse:
// capWidthOffset=size.Width;
// break;
// }
// return capWidthOffset;
//}
///// <summary>
///// Returns true if source node is on the left side of the target node.
///// </summary>
///// <param name="source">Reference to source node.</param>
///// <param name="target">Reference to target node.</param>
///// <returns>True if source is on the left side of target.</returns>
//protected bool IsOnLeftSide(Node source, Node target)
//{
// if((source.BoundsRelative.Left+source.BoundsRelative.Width/2)>target.BoundsRelative.Left)
// return true;
// return false;
//}
/// <summary>
/// Returns new instance of pen object for node connector line. Caller is responsible for
/// disposing of this object.
/// </summary>
/// <param name="info">Node connector display info.</param>
/// <returns>New instance of Pen object.</returns>
protected Pen GetLinePen(ConnectorRendererEventArgs info)
{
Pen pen = new Pen(info.NodeConnector.LineColor, info.NodeConnector.LineWidth);
pen.DashStyle = info.NodeConnector.DashStyle;
return pen;
}
///// <summary>
///// Returns new instance of pen object for the end node connector line. Caller is responsible for
///// disposing of this object.
///// </summary>
///// <param name="info">Node connector display info.</param>
///// <returns>New instance of Pen object.</returns>
//protected Pen GetEndLinePen(ConnectorRendererEventArgs info)
//{
// return new Pen(info.NodeConnector.LineColor,EndLineWidth);
//}
///// <summary>
///// Returns new instance of pen object for the node underline line. Caller is responsible for
///// disposing of this object.
///// </summary>
///// <param name="info">Node connector display info.</param>
///// <returns>New instance of Pen object.</returns>
//protected Pen GetEndUnderlinePen(ConnectorRendererEventArgs info)
//{
// return new Pen(info.NodeConnector.LineColor,EndLineWidth);
//}
//private int EndLineWidth
//{
// get {return 1;}
//}
// /// <summary>
// /// Draws straight line connector between start and end point.
// /// </summary>
// /// <param name="info">Node connector display info.</param>
// /// <param name="pStart">Start point.</param>
// /// <param name="pEnd">End point.</param>
// /// <param name="pEndUnderLine">Underline end point if any.</param>
// protected void DrawStraightLineConnector(ConnectorRendererEventArgs info, Point pStart, Point pEnd)
// {
// using (Pen pen = this.GetLinePen(info))
// {
// if (pen.DashStyle != DashStyle.Solid)
// {
// SmoothingMode sm = info.Graphics.SmoothingMode;
// info.Graphics.SmoothingMode = SmoothingMode.Default;
// info.Graphics.DrawLine(pen, pStart, pEnd);
// info.Graphics.SmoothingMode = sm;
// }
// else
// info.Graphics.DrawLine(pen, pStart, pEnd);
// }
// }
// /// <summary>
// /// Draws straight line connector between start and end point.
// /// </summary>
// /// <param name="info">Node connector display info.</param>
// /// <param name="pStart">Start point.</param>
// /// <param name="pEnd">End point.</param>
// /// <param name="pEndUnderLine">Underline end point if any.</param>
// protected void DrawLineConnector(ConnectorRendererEventArgs info,Point pStart,Point pEnd, Point pEndUnderLine)
// {
// if(info.NodeConnector.LineWidth>1)
// {
// // Merge lines nicely by filling and creating path...
// int rootLineWidth=this.EndLineWidth;
// int lineWidth=info.NodeConnector.LineWidth;
// using(Brush brush=GetLineBrush(info))
// {
// GraphicsPath path=GetConnectingPath(pStart,pEnd,lineWidth,rootLineWidth,info.IsRootNode,!(IsAbove(info.FromNode,info.ToNode) || IsBelow(info.FromNode,info.ToNode)));
// info.Graphics.FillPath(brush,path);
// }
// }
// else
// {
// using(Pen pen=this.GetLinePen(info))
// {
// info.Graphics.DrawLine(pen,pStart,pEnd);
// }
// }
// if(!pEndUnderLine.IsEmpty)
// {
// using(Pen pen=this.GetEndUnderlinePen(info))
// {
// info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
// }
// }
// }
// private GraphicsPath GetConnectingPath(Point pStart, Point pEnd, int lineStartWidth, int lineEndWidth, bool bRoot, bool bRootSide)
// {
// int direction=1;
// if(pStart.X>pEnd.X)
// direction=-1;
// lineStartWidth++;
// lineEndWidth++;
// GraphicsPath path=new GraphicsPath();
// if(bRoot && !bRootSide)
// {
// path.AddLine(pStart.X,pStart.Y,pStart.X+lineStartWidth*direction,pStart.Y);
//// if(direction>0)
//// path.AddLine(pEnd.X+lineEndWidth*direction,pEnd.Y,pEnd.X,pEnd.Y);
//// else
//// path.AddLine(pEnd.X,pEnd.Y,pEnd.X+lineEndWidth*direction,pEnd.Y);
// if(direction>0)
// {
// path.AddLine(pStart.X+lineStartWidth*direction,pStart.Y, pEnd.X, pEnd.Y);
// path.AddLine(pEnd.X, pEnd.Y, pEnd.X, pEnd.Y + lineEndWidth*direction);
// path.AddLine(pEnd.X, pEnd.Y + lineEndWidth*direction, pStart.X, pStart.Y);
// }
// else
// path.AddLine(pEnd.X, pEnd.Y, pEnd.X, pEnd.Y + lineEndWidth*direction);
// path.CloseAllFigures();
//// if(Math.Abs(pEnd.Y-pStart.Y)<=8)
//// path.Widen(SystemPens.Highlight);
// }
// else
// {
// int offsetStart=lineStartWidth/2;
// int offsetEnd=lineEndWidth/2;
// path.AddLine(pStart.X,pStart.Y-offsetStart,pStart.X,pStart.Y+offsetStart);
// path.AddLine(pEnd.X,pEnd.Y+offsetEnd,pEnd.X,pEnd.Y-offsetEnd);
// path.AddLine(pEnd.X,pEnd.Y-offsetEnd,pStart.X,pStart.Y-offsetStart);
// path.CloseAllFigures();
// }
// return path;
// }
// protected Brush GetLineBrush(ConnectorRendererEventArgs info)
// {
// return new SolidBrush(info.NodeConnector.LineColor);
// }
// protected void DrawEndLine(ConnectorRendererEventArgs info,Point pStart,Point pEnd,Point pEndUnderLine)
// {
// if(pEndUnderLine.IsEmpty)
// {
// switch(info.NodeConnector.EndCap)
// {
// case eConnectorCap.Ellipse:
// {
// using(Pen pen=this.GetEndLinePen(info))
// {
// Size endCapSize=info.NodeConnector.EndCapSize;
// if(pStart.X<pEnd.X)
// info.Graphics.DrawEllipse(pen,pEnd.X-1,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
// else
// info.Graphics.DrawEllipse(pen,pEnd.X-endCapSize.Width,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
// }
// break;
// }
// case eConnectorCap.Arrow:
// {
// using(Pen pen=this.GetEndLinePen(info))
// {
// // Connects connector line to arrow
// int direction=1;
// if(pStart.X>pEnd.X)
// direction=-1;
// info.Graphics.DrawLine(pen,pEnd,new Point(pEnd.X+info.NodeConnector.EndCapSize.Width/3*direction,pEnd.Y));
// Size endCapSize=info.NodeConnector.EndCapSize;
// GraphicsPath arrow=GetArrowPath(endCapSize,pStart,pEnd);
// info.Graphics.DrawPath(pen,arrow);
// }
// break;
// }
// }
// }
// else
// {
// using(Pen pen=this.GetEndUnderlinePen(info))
// {
// info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
// // Connect underline to expand part
// if(NodeDisplay.DrawExpandPart(info.ToNode))
// {
// Rectangle re=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,info.ToNode,info.Offset);
// Point p2=new Point((re.X>pEndUnderLine.X?re.X:re.Right)+(re.Width/2*(re.X>pEndUnderLine.X?1:-1)),re.Bottom);
// Point p1=new Point(p2.X,pEndUnderLine.Y+(pEndUnderLine.Y>p2.Y?(p2.Y-pEndUnderLine.Y)/2:-(p2.Y-pEndUnderLine.Y)/2));
// info.Graphics.DrawCurve(pen,new Point[]{pEndUnderLine,p1,p2},.5f);
// }
// }
// }
// }
// private GraphicsPath GetArrowPath(Size capSize,Point pStart,Point pEnd)
// {
// GraphicsPath path=new GraphicsPath();
// int direction=1;
// if(pStart.X>pEnd.X)
// direction=-1;
// pEnd.X+=(GetCapWidthOffset(eConnectorCap.Arrow,capSize)*direction);
// path.AddLine(pEnd.X,pEnd.Y,pEnd.X-capSize.Width*direction,pEnd.Y-capSize.Height/2);
// path.AddLine(pEnd.X-(2*capSize.Width/3*direction),pEnd.Y,pEnd.X-capSize.Width*direction,pEnd.Y+capSize.Height/2);
// path.CloseAllFigures();
// return path;
// }
//internal virtual ConnectorPointInfo GetConnectorPointInfo(ConnectorRendererEventArgs info, Point pStart, Point pEnd)
//{
// ConnectorPointInfo pointInfo=new ConnectorPointInfo();
// int xMulti=1/*, yMulti=1*/;
// int lineWidth=info.NodeConnector.LineWidth;
// // used for direction control
// if(pStart.X>pEnd.X)
// xMulti=-1;
// //if(pStart.Y>pEnd.Y)
// // yMulti=-1;
// if(info.ConnectorPoints!=null)
// {
// Point connPointsOffset=info.ToNode.BoundsRelative.Location;
// connPointsOffset.Offset(info.Offset.X,info.Offset.Y);
// GraphicsPath path=new GraphicsPath();
// pointInfo.Points1=new Point[info.ConnectorPoints.Count+2];
// pointInfo.Points1[0]=pStart;
// pointInfo.Points1[pointInfo.Points1.Length-1]=pEnd;
// if(lineWidth>1)
// {
// pointInfo.Points2=new Point[info.ConnectorPoints.Count+2];
// pointInfo.Points2[pointInfo.Points2.Length-1]=pStart;
// pointInfo.Points2[0]=pEnd;
// int i=pointInfo.Points1.Length-2;
// int k=1;
// foreach(Point pcp in info.ConnectorPoints)
// {
// pointInfo.Points1[i]=pcp;
// pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
// pointInfo.Points2[k]=new Point(pcp.X+lineWidth*xMulti,pcp.Y);
// pointInfo.Points2[k].Offset(connPointsOffset.X,connPointsOffset.Y);
// k++;
// i--;
// }
// }
// else
// {
// int i=pointInfo.Points1.Length-2;
// foreach(Point pcp in info.ConnectorPoints)
// {
// pointInfo.Points1[i]=pcp;
// pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
// i--;
// }
// }
// }
// return pointInfo;
//}
}
}
/// <summary>
/// Represents custom connector path info.
/// </summary>
internal class ConnectorPointInfo
{
public Point[] Points1=null;
public Point[] Points2=null;
}
}

View File

@ -0,0 +1,351 @@
using System;
using System.Drawing;
using DevComponents.AdvTree.Layout;
using System.Collections;
using DevComponents.DotNetBar;
using System.ComponentModel;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Summary description for NodeDisplay.
/// </summary>
public class NodeDisplay
{
#region Private Variables
private Point m_Offset=Point.Empty;
private Point m_LockedOffset=Point.Empty;
private AdvTree m_Tree=null;
internal ArrayList _PaintedNodes = new ArrayList(100);
#if !TRIAL
internal static bool keyInvalid=false;
#endif
#endregion
/// <summary>Creates new instance of the class</summary>
/// <param name="tree">Object to initialize class with.</param>
public NodeDisplay(AdvTree tree)
{
m_Tree=tree;
}
/// <summary>
/// Paints the layout on canvas.
/// </summary>
public virtual void Paint(Graphics g, Rectangle clipRectangle)
{
}
/// <summary>
/// Gets or sets the offset of the tree content relative to the size of the container control.
/// </summary>
public virtual Point Offset
{
get
{
if(!m_LockedOffset.IsEmpty)
return m_LockedOffset;
Node displayNode=m_Tree.GetDisplayRootNode();
if(displayNode==null)
return Point.Empty;;
Size nodesSize = m_Tree.GetScreenSize(new Size(m_Tree.NodeLayout.Width, m_Tree.NodeLayout.Height));
return m_Tree.GetLayoutPosition(m_Offset);
}
set {m_Offset=value;}
}
/// <summary>Gets or sets whether offset is locked, i.e. cannot be changed.</summary>
public bool LockOffset
{
get {return (!m_LockedOffset.IsEmpty);}
set
{
if(value)
m_LockedOffset=this.Offset;
else
m_LockedOffset=Point.Empty;
}
}
/// <summary>
/// Sets locked offset to specific value. Point.Empty means there is no locked offset set.
/// </summary>
/// <param name="p">New locked offset.</param>
public void SetLockedOffset(Point p)
{
m_LockedOffset=p;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public Point GetLockedOffset()
{
return m_LockedOffset;
}
/// <summary>
/// Returns the default offset for the tree content relative to the size of the container.
/// </summary>
public virtual Point DefaultOffset
{
get
{
Node displayNode=m_Tree.GetDisplayRootNode();
if(displayNode==null)
return Point.Empty;;
//if(m_Tree.NodeLayout is NodeMapLayout && m_Tree.Nodes.Count>0)
//{
// if(!m_Tree.CenterContent)
// return new Point(Math.Abs(displayNode.ChildNodesBounds.Left),Math.Abs(displayNode.ChildNodesBounds.Top));
// else
// return new Point(m_Tree.SelectionBoxSize+(m_Tree.Width - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Width) / 2 + Math.Abs(displayNode.ChildNodesBounds.Left),
// m_Tree.SelectionBoxSize + (m_Tree.Height - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Height) / 2 + Math.Abs(displayNode.ChildNodesBounds.Top));
//}
//if(m_Tree.NodeLayout is Layout.NodeDiagramLayout)
//{
// if(!m_Tree.CenterContent)
// return m_Tree.ClientRectangle.Location;
// else
// return new Point((m_Tree.Width-m_Tree.NodeLayout.Width)/2,(m_Tree.Height-m_Tree.NodeLayout.Height)/2);
//}
//else
return m_Tree.ClientRectangle.Location;
}
}
/// <summary>
/// Gets or sets the reference to the tree control managed by display class.
/// </summary>
protected virtual AdvTree Tree
{
get {return m_Tree;}
set {m_Tree=value;}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static Rectangle GetNodeRectangle(eNodeRectanglePart part, Node node, Point offset)
{
Rectangle r=Rectangle.Empty;
if(part==eNodeRectanglePart.CellsBounds)
{
r=node.CellsBoundsRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(node.BoundsRelative.Location);
}
}
else if (part == eNodeRectanglePart.ExpandHitTestBounds)
{
Rectangle nodeBounds = GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, offset);
r = node.ExpandPartRectangleRelative;
if (!r.IsEmpty)
{
r.Offset(offset);
r.Offset(node.BoundsRelative.Location);
}
r.Y = nodeBounds.Y;
r.Height = nodeBounds.Height;
r.Inflate(1, 0);
}
else if(part==eNodeRectanglePart.ExpandBounds)
{
r=node.ExpandPartRectangleRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(node.BoundsRelative.Location);
}
}
else if(part==eNodeRectanglePart.CommandBounds)
{
r=node.CommandBoundsRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(node.BoundsRelative.Location);
}
}
else if(part==eNodeRectanglePart.NodeContentBounds)
{
r=node.ContentBounds;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(node.BoundsRelative.Location);
}
}
else if(part==eNodeRectanglePart.NodeBounds)
{
r=node.BoundsRelative;
if(!r.IsEmpty)
r.Offset(offset);
}
else if (part == eNodeRectanglePart.ChildNodeBounds)
{
r = node.ChildNodesBounds;
if (!r.IsEmpty)
{
//r.Offset(node.Bounds.Location);
r.Offset(offset);
}
}
else if (part == eNodeRectanglePart.ColumnsBounds && HasColumnsVisible(node))
{
r = node.NodesColumns.Bounds;
if(!r.IsEmpty)
r.Offset(offset);
}
return r;
}
internal static bool HasColumnsVisible(Node node)
{
return node.Expanded && node.HasColumns && node.NodesColumnsHeaderVisible;
}
internal static Rectangle GetCellRectangle(eCellRectanglePart part, Cell cell, Point offset)
{
Rectangle r=Rectangle.Empty;
// If cell parent is not assigned rectangle cannot be returned.
if(cell.Parent==null)
return r;
if(part==eCellRectanglePart.CheckBoxBounds)
{
r=cell.CheckBoxBoundsRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(cell.Parent.BoundsRelative.Location);
}
}
else if(part==eCellRectanglePart.ImageBounds)
{
r=cell.ImageBoundsRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(cell.Parent.BoundsRelative.Location);
}
}
else if(part==eCellRectanglePart.TextBounds)
{
r=cell.TextContentBounds;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(cell.Parent.BoundsRelative.Location);
}
}
else if(part==eCellRectanglePart.CellBounds)
{
r=cell.BoundsRelative;
if(!r.IsEmpty)
{
r.Offset(offset);
r.Offset(cell.Parent.BoundsRelative.Location);
}
}
return r;
}
internal static bool DrawExpandPart(Node node)
{
if(node.Nodes.Count>0 && node.ExpandVisibility!=eNodeExpandVisibility.Hidden || node.ExpandVisibility==eNodeExpandVisibility.Visible)
return true;
return false;
}
protected NodeExpandDisplay GetExpandDisplay(eExpandButtonType e)
{
NodeExpandDisplay d=null;
switch(e)
{
case eExpandButtonType.Rectangle:
d = new NodeExpandRectDisplay();
break;
case eExpandButtonType.Triangle:
d = new NodeExpandTriangleDisplay();
break;
case eExpandButtonType.Ellipse:
d=new NodeExpandEllipseDisplay();
break;
case eExpandButtonType.Image:
d=new NodeExpandImageDisplay();
break;
}
return d;
}
protected bool IsRootNode(Node node)
{
return NodeOperations.IsRootNode(m_Tree,node);
}
protected ElementStyle GetDefaultNodeStyle()
{
ElementStyle style=new ElementStyle();
style.TextColorSchemePart=eColorSchemePart.ItemText;
return style;
}
public void MoveHostedControls()
{
Point offset = this.Offset;
float zoom = this.Tree.Zoom;
foreach (Cell cell in this.Tree.HostedControlCells)
{
System.Windows.Forms.Control cellHostedControl = cell.HostedControl;
if (cellHostedControl == null) continue;
Rectangle bounds = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, cell, offset);
Rectangle screenBounds = this.Tree.GetScreenRectangle(bounds);
if (!bounds.IsEmpty && cellHostedControl.Bounds != screenBounds)
{
if (zoom != 1)
{
cell.HostedControlSize = bounds.Size;
cell.IgnoreHostedControlSizeChange = true;
}
else
{
cell.HostedControlSize = Size.Empty;
if (screenBounds.Height > cellHostedControl.Height && cellHostedControl.Height > 0)
{
screenBounds.Y += (screenBounds.Height - cellHostedControl.Height) / 2;
screenBounds.Height = cellHostedControl.Height;
}
}
cellHostedControl.Bounds = screenBounds;
if (zoom != 1)
cell.IgnoreHostedControlSizeChange = false;
if (cell.Parent != null)
{
bool visible = NodeOperations.GetIsNodeVisible(cell.Parent) && cell.IsVisible;
if (visible != cellHostedControl.Visible)
cellHostedControl.Visible = visible;
}
}
}
}
public ArrayList PaintedNodes
{
get
{
return _PaintedNodes;
}
}
internal virtual void PaintColumnHeaders(ColumnHeaderCollection columns, Graphics g, bool treeControlHeader)
{
}
}
}

View File

@ -0,0 +1,139 @@
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree
{
namespace Display
{
/// <summary>
/// Base class for node expand button display.
/// </summary>
public abstract class NodeExpandDisplay
{
/// <summary>Creates new instance of the class</summary>
public NodeExpandDisplay()
{
}
/// <summary>Draws expand button.</summary>
/// <param name="e">Context parameters for drawing expand button.</param>
public abstract void DrawExpandButton(NodeExpandPartRendererEventArgs e);
protected Pen GetBorderPen(NodeExpandPartRendererEventArgs e)
{
if(!e.BorderColor.IsEmpty)
return new Pen(e.BorderColor,1);
if (_ColorTable != null)
{
bool expanded = e.Node.Expanded;
TreeExpandColorTable ct = GetExpandColorTable(e);
if (ct == null) return null;
if (expanded)
{
// Collapse node colors
if (!e.IsMouseOver && ct.CollapseBorder != null)
return ct.CollapseBorder.CreatePen();
else if (e.IsMouseOver && ct.CollapseMouseOverBorder != null)
return ct.CollapseMouseOverBorder.CreatePen();
}
else
{
// Expand node colors
if (!e.IsMouseOver && ct.ExpandBorder != null)
return ct.ExpandBorder.CreatePen();
else if (e.IsMouseOver && ct.ExpandMouseOverBorder != null)
return ct.ExpandMouseOverBorder.CreatePen();
}
}
return null;
}
private TreeExpandColorTable GetExpandColorTable(NodeExpandPartRendererEventArgs e)
{
TreeExpandColorTable ct = null;
if (e.ExpandButtonType == eExpandButtonType.Rectangle)
ct = _ColorTable.ExpandRectangle;
else if (e.ExpandButtonType == eExpandButtonType.Triangle)
ct = _ColorTable.ExpandTriangle;
else if (e.ExpandButtonType == eExpandButtonType.Ellipse)
ct = _ColorTable.ExpandEllipse;
return ct;
}
protected Pen GetExpandPen(NodeExpandPartRendererEventArgs e)
{
if (e.ExpandLineColor.IsEmpty)
{
TreeExpandColorTable ct = GetExpandColorTable(e);
if (ct != null)
{
bool expanded = e.Node.Expanded;
if (expanded)
{
// Collapse node colors
if (!e.IsMouseOver && ct.CollapseForeground != null)
return ct.CollapseForeground.CreatePen(Dpi.Width1);
else if (e.IsMouseOver && ct.CollapseMouseOverForeground != null)
return ct.CollapseMouseOverForeground.CreatePen(Dpi.Width1);
}
else
{
// Collapse node colors
if (!e.IsMouseOver && ct.ExpandForeground != null)
return ct.ExpandForeground.CreatePen(Dpi.Width1);
else if (e.IsMouseOver && ct.ExpandMouseOverForeground != null)
return ct.ExpandMouseOverForeground.CreatePen(Dpi.Width1);
}
}
return GetBorderPen(e);
}
return new Pen(e.ExpandLineColor,1);
}
protected Brush GetBackgroundBrush(NodeExpandPartRendererEventArgs e)
{
if (e.BackColor.IsEmpty && e.BackColor2.IsEmpty)
{
bool expanded = e.Node.Expanded;
TreeExpandColorTable ct = GetExpandColorTable(e);
if (ct == null) return null;
if (expanded)
{
// Collapse node colors
if (!e.IsMouseOver && ct.CollapseFill != null)
return ct.CollapseFill.CreateBrush(e.ExpandPartBounds);
else if (e.IsMouseOver && ct.CollapseMouseOverFill != null)
return ct.CollapseMouseOverFill.CreateBrush(e.ExpandPartBounds);
}
else
{
// Expand node colors
if (!e.IsMouseOver && ct.ExpandFill != null)
return ct.ExpandFill.CreateBrush(e.ExpandPartBounds);
else if (e.IsMouseOver && ct.ExpandMouseOverFill != null)
return ct.ExpandMouseOverFill.CreateBrush(e.ExpandPartBounds);
}
return null;
}
if(e.BackColor2.IsEmpty)
return new SolidBrush(e.BackColor);
System.Drawing.Drawing2D.LinearGradientBrush brush=DisplayHelp.CreateLinearGradientBrush(e.ExpandPartBounds,e.BackColor,e.BackColor2,e.BackColorGradientAngle);
//brush.SetSigmaBellShape(0.8f);
return brush;
}
private TreeColorTable _ColorTable;
public TreeColorTable ColorTable
{
get { return _ColorTable; }
set { _ColorTable = value; }
}
}
}
}

View File

@ -0,0 +1,57 @@
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents class that paints elliptical expand button.
/// </summary>
public class NodeExpandEllipseDisplay:NodeExpandDisplay
{
/// <summary>Draws ellipse type expand button.</summary>
/// <param name="e">Expand context drawing information.</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
if(e.ExpandPartBounds.IsEmpty)
return;
Brush brush=GetBackgroundBrush(e);
if(brush!=null)
{
e.Graphics.FillEllipse(brush,e.ExpandPartBounds);
brush.Dispose();
}
Pen pen=GetBorderPen(e);
if (pen != null)
{
SmoothingMode sm = e.Graphics.SmoothingMode;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(pen, e.ExpandPartBounds);
e.Graphics.SmoothingMode = sm;
pen.Dispose();
pen = null;
}
if(e.Node.Expanded)
{
pen = GetExpandPen(e);
if (pen != null)
{
e.Graphics.DrawLine(pen, e.ExpandPartBounds.X + 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2, e.ExpandPartBounds.Right - 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2);
pen.Dispose();
}
}
else
{
pen = GetExpandPen(e);
if (pen != null)
{
e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2,e.ExpandPartBounds.Right-2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2);
e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Y+2,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Bottom-2);
pen.Dispose();
}
}
}
}
}

View File

@ -0,0 +1,25 @@
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents expand button display using predefined images.
/// </summary>
public class NodeExpandImageDisplay:NodeExpandDisplay
{
/// <summary>
/// Draws image type expand button.
/// </summary>
/// <param name="e">Expand context information</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
if(e.Node.Expanded)
{
if(e.ExpandImageCollapse!=null)
e.Graphics.DrawImage(e.ExpandImageCollapse,e.ExpandPartBounds);
}
else if(e.ExpandImage!=null)
e.Graphics.DrawImage(e.ExpandImage,e.ExpandPartBounds);
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Drawing;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents event arguments for RenderExpandPart event.
/// </summary>
public class NodeExpandPartRendererEventArgs:EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to Node object being rendered.
/// </summary>
public DevComponents.AdvTree.Node Node=null;
/// <summary>Expand part bounds</summary>
public Rectangle ExpandPartBounds=Rectangle.Empty;
/// <summary>Expand part border color</summary>
public Color BorderColor=Color.Empty;
/// <summary>Expand part line color</summary>
public Color ExpandLineColor=Color.Empty;
/// <summary>Expand part background color</summary>
public Color BackColor=Color.Empty;
/// <summary>Expand part target gradient background color</summary>
public Color BackColor2=Color.Empty;
/// <summary>Gradient angle</summary>
public int BackColorGradientAngle=90;
/// <summary>Expand part image when node is expanded</summary>
public Image ExpandImage=null;
/// <summary>Expand part image when node is collapsed</summary>
public Image ExpandImageCollapse=null;
/// <summary>Internal support for expand button types</summary>
internal eExpandButtonType ExpandButtonType=eExpandButtonType.Ellipse;
/// <summary>Gets whether mouse is over expand part</summary>
public bool IsMouseOver = false;
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
public NodeExpandPartRendererEventArgs(Graphics g)
{
this.Graphics = g;
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents class that paints rectangular expand button.
/// </summary>
public class NodeExpandRectDisplay:NodeExpandDisplay
{
/// <summary>
/// Draw rectangular type expand button.
/// </summary>
/// <param name="e">Expand button context information.</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
if(e.ExpandPartBounds.IsEmpty)
return;
Brush brush=GetBackgroundBrush(e);
if(brush!=null)
{
e.Graphics.FillRectangle(brush,e.ExpandPartBounds);
brush.Dispose();
}
Pen pen = GetBorderPen(e);
if (pen != null)
{
e.Graphics.DrawRectangle(pen, e.ExpandPartBounds);
pen.Dispose();
pen = null;
}
if(e.Node.Expanded)
{
pen = GetExpandPen(e);
if (pen != null)
{
e.Graphics.DrawLine(pen, e.ExpandPartBounds.X + 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2, e.ExpandPartBounds.Right - 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2);
pen.Dispose();
}
}
else
{
pen = GetExpandPen(e);
if (pen != null)
{
e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2,e.ExpandPartBounds.Right-2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2);
e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Y+2,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Bottom-2);
pen.Dispose();
}
}
}
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
internal class NodeExpandTriangleDisplay : NodeExpandDisplay
{
/// <summary>
/// Draw triangular type expand button.
/// </summary>
/// <param name="e">Expand button context information.</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
if (e.ExpandPartBounds.IsEmpty)
return;
SmoothingMode sm = e.Graphics.SmoothingMode;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
int pw = Dpi.Width5;
Rectangle r = new Rectangle(e.ExpandPartBounds.X , e.ExpandPartBounds.Y + (e.ExpandPartBounds.Height - 8) / 2, pw, Dpi.Height8);
GraphicsPath path = null;
if (e.Node.Expanded)
{
path = new GraphicsPath();
path.AddLine(r.X, r.Y + pw, r.X + pw, r.Y);
path.AddLine(r.X + pw, r.Y, r.X + pw, r.Y + pw);
path.CloseAllFigures();
}
else
{
path = new GraphicsPath();
path.AddLine(r.X, r.Y, r.X, r.Bottom);
path.AddLine(r.X, r.Bottom, r.X + Dpi.Width4, r.Y + r.Height / 2);
path.CloseAllFigures();
}
Brush brush = GetBackgroundBrush(e);
if (brush != null)
{
e.Graphics.FillPath(brush, path);
brush.Dispose();
}
Pen pen = GetBorderPen(e);
if(pen!=null)
{
e.Graphics.DrawPath(pen, path);
pen.Dispose();
}
e.Graphics.SmoothingMode = sm;
if(path!=null) path.Dispose();
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using DevComponents.AdvTree.Layout;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
internal class NodeGroupLineDisplay
{
private static readonly int LineMargin = 4;
public void DrawGroupLine(NodeRendererEventArgs e)
{
Color lineColor = e.Color;
Node node = e.Node;
if (lineColor.IsEmpty || lineColor.A == 0 || node.Cells.Count == 0) return;
Graphics g = e.Graphics;
Rectangle r = node.Bounds;
Cell lastCell = node.Cells[node.Cells.Count - 1];
if (lastCell.CheckBoxVisible && CellLayout.GetCheckBoxHorizontalAlign(lastCell.CheckBoxAlignment, true, eView.Tile) == eHorizontalAlign.Right)
{
r.Width -= (lastCell.CheckBoxBounds.Right - r.X) + LineMargin;
r.X = lastCell.CheckBoxBounds.Right + LineMargin;
}
else if (!lastCell.ImageBoundsRelative.IsEmpty && CellLayout.GetHorizontalAlign(lastCell.ImageAlignment, true, eView.Tile) == eHorizontalAlign.Right)
{
r.Width -= (lastCell.ImageBounds.Right - r.X) + LineMargin;
r.X = lastCell.ImageBounds.Right + LineMargin;
}
else if (e.Style.TextAlignment == eStyleTextAlignment.Near)
{
Rectangle textBounds = lastCell.TextBounds;
if (lastCell.TextMarkupBody == null)
textBounds.Width = TextDrawing.MeasureString(g, lastCell.Text, e.Style.Font).Width;
r.Width -= (textBounds.Right - r.X) + LineMargin;
r.X = textBounds.Right + LineMargin;
}
else
return;
using (Pen pen = new Pen(lineColor, 1))
{
g.DrawLine(pen, r.X, r.Y + r.Height / 2, r.Right, r.Y + r.Height / 2);
}
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Summary description for NodeRendererEventArgs.
/// </summary>
public class NodeRendererEventArgs:EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to Node object being rendered.
/// </summary>
public DevComponents.AdvTree.Node Node=null;
/// <summary>
/// Gets or sets the absolute node bounds.
/// </summary>
public Rectangle NodeBounds=Rectangle.Empty;
/// <summary>
/// Gets or sets the reference to element style for rendered node or cell. Style provided here is the style
/// for current node or cell state.
/// </summary>
public ElementStyle Style=null;
/// <summary>
/// Gets or sets color that is passed to renderer. May be Color.Empty.
/// </summary>
public Color Color = Color.Empty;
/// <summary>
/// Creates new instance of the class.
/// </summary>
public NodeRendererEventArgs()
{
}
public NodeRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style)
: this(g, node, bounds, style, Color.Empty)
{
}
public NodeRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style, Color color)
{
this.Graphics = g;
this.Node = node;
this.NodeBounds = bounds;
this.Style = style;
this.Color = color;
}
}
}

View File

@ -0,0 +1,190 @@
using System.Drawing;
using DevComponents.WinForms.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represent class that paints selection around node.
/// </summary>
internal class NodeSelectionDisplay
{
public void PaintSelection(SelectionRendererEventArgs info)
{
if (info.SelectionBoxStyle == eSelectionStyle.HighlightCells)
PaintHighlightCellsSelectionStyle(info);
else if (info.SelectionBoxStyle == eSelectionStyle.FullRowSelect)
PaintFullRowSelectSelectionStyle(info);
else if (info.SelectionBoxStyle == eSelectionStyle.NodeMarker)
PaintNodeMarkerSelectionStyle(info);
}
public void PaintHotTracking(SelectionRendererEventArgs info)
{
// Full row is just a rectangle with the background...
Shape[] fullRowShapes = GetHotTrackingShapes();
Graphics g = info.Graphics;
Rectangle bounds = info.Bounds;
bounds.Width--;
bounds.Height--;
foreach (Shape shape in fullRowShapes)
{
shape.Paint(g, bounds);
}
}
private void PaintFullRowSelectSelectionStyle(SelectionRendererEventArgs info)
{
// Full row is just a rectangle with the background...
Shape[] fullRowShapes = GetFullRowShapes(info.TreeActive);
Graphics g = info.Graphics;
Rectangle bounds = info.Bounds;
//bounds.Width--;
//bounds.Height--;
foreach (Shape shape in fullRowShapes)
{
shape.Paint(g, bounds);
}
}
Shape[] _FullRowShapes = null;
private Shape[] GetFullRowShapes(bool treeActive)
{
if (_FullRowShapes == null)
{
_FullRowShapes = new Shape[1];
_FullRowShapes[0] = new RectangleShape();
}
RectangleShape shape = (RectangleShape)_FullRowShapes[0];
SelectionColorTable colors = treeActive ? _SelectionColors.FullRowSelect : _SelectionColors.FullRowSelectInactive;
shape.Fill = colors.Fill;
shape.Border = colors.Border;
return _FullRowShapes;
}
private void PaintHighlightCellsSelectionStyle(SelectionRendererEventArgs info)
{
// Full row is just a rectangle with the background...
Shape[] fullRowShapes = GetHighlightCellsShapes(info.TreeActive);
Graphics g = info.Graphics;
Rectangle bounds = info.Bounds;
bounds.Width--;
bounds.Height--;
foreach (Shape shape in fullRowShapes)
{
shape.Paint(g, bounds);
}
}
Shape[] _HighlightCellsShapes = null;
private Shape[] GetHighlightCellsShapes(bool treeActive)
{
SelectionColorTable colorTable = treeActive ? _SelectionColors.HighlightCells : _SelectionColors.HighlightCellsInactive;
if (_HighlightCellsShapes == null || ((RectangleShape)_HighlightCellsShapes[0]).CornerRadius != null && ((RectangleShape)_HighlightCellsShapes[0]).CornerRadius.TopLeft != colorTable.BorderCornerRadius)
{
_HighlightCellsShapes = new Shape[1];
RectangleShape rectShape = new RectangleShape();
if (colorTable.BorderCornerRadius > 0)
{
rectShape.CornerRadius = new CornerRadius(colorTable.BorderCornerRadius);
RectangleShape inner = new RectangleShape();
rectShape.Content = inner;
}
_HighlightCellsShapes[0] = rectShape;
}
RectangleShape shape = (RectangleShape)_HighlightCellsShapes[0];
shape.Fill = colorTable.Fill;
shape.Border = colorTable.Border;
if (shape.Content != null)
{
shape = (RectangleShape)shape.Content;
shape.Border = colorTable.InnerBorder;
}
return _HighlightCellsShapes;
}
Shape[] _HotTrackingShapes = null;
private Shape[] GetHotTrackingShapes()
{
if (_HotTrackingShapes == null)
{
_HotTrackingShapes = new Shape[1];
RectangleShape rectShape = new RectangleShape();
rectShape.CornerRadius = new CornerRadius(2);
RectangleShape inner = new RectangleShape();
//inner.CornerRadius = new CornerRadius(2);
rectShape.Content = inner;
_HotTrackingShapes[0] = rectShape;
}
SelectionColorTable colorTable = _SelectionColors.NodeHotTracking;
RectangleShape shape = (RectangleShape)_HotTrackingShapes[0];
shape.Fill = colorTable.Fill;
shape.Border = colorTable.Border;
shape = (RectangleShape)shape.Content;
shape.Border = colorTable.InnerBorder;
return _HotTrackingShapes;
}
private void PaintNodeMarkerSelectionStyle(SelectionRendererEventArgs info)
{
Rectangle inside = info.Bounds;
int borderWidth = 4;
inside.Inflate(1, 1);
inside.Width--;
inside.Height--;
Rectangle outside = info.Bounds;
outside.Inflate(borderWidth, borderWidth);
outside.Width--;
outside.Height--;
SelectionColorTable colorTable = info.TreeActive ? _SelectionColors.NodeMarker : _SelectionColors.NodeMarkerInactive;
if (colorTable.Border != null)
{
Pen pen = colorTable.Border.CreatePen();
if (pen != null)
{
info.Graphics.DrawRectangle(pen, inside);
info.Graphics.DrawRectangle(pen, outside);
pen.Dispose();
}
}
if (colorTable.Fill != null)
{
Brush brush = colorTable.Fill.CreateBrush(outside);
if (brush != null)
{
Region region = new Region(outside);
region.Exclude(inside);
info.Graphics.FillRegion(brush, region);
brush.Dispose();
}
}
}
private TreeSelectionColors _SelectionColors = null;
public TreeSelectionColors SelectionColors
{
get { return _SelectionColors; }
set { _SelectionColors = value; }
}
}
internal class NodeSelectionDisplayInfo
{
public Node Node=null;
public Graphics Graphics=null;
public Rectangle Bounds=Rectangle.Empty;
public Color BorderColor=Color.Empty;
public Color FillColor=Color.Empty;
public int Width=4;
}
}

View File

@ -0,0 +1,270 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents default system node and cell renderer.
/// </summary>
public class NodeSystemRenderer:TreeRenderer
{
#region Private Variables
private NodeExpandEllipseDisplay m_NodeExpandEllipseDisplay=new NodeExpandEllipseDisplay();
private NodeExpandRectDisplay m_NodeExpandRectDisplay=new NodeExpandRectDisplay();
private NodeExpandTriangleDisplay m_NodeExpandTriangleDisplay = new NodeExpandTriangleDisplay();
private NodeExpandImageDisplay m_NodeExpandImageDisplay=new NodeExpandImageDisplay();
private ElementStyleDisplayInfo m_ElementStyleDisplayInfo=new ElementStyleDisplayInfo();
private NodeSelectionDisplay m_SelectionDisplay=new NodeSelectionDisplay();
private LineConnectorDisplay m_LineConnectorDisplay=null;
private DragDropMarkerDisplay m_DragDropMarkerDisplay = new DragDropMarkerDisplay();
private ColumnHeaderDisplay m_ColumnHeaderDisplay = new ColumnHeaderDisplay();
private Office2007CheckBoxItemPainter m_CheckBoxPainter = new Office2007CheckBoxItemPainter();
private NodeGroupLineDisplay _GroupLineDisplay = new NodeGroupLineDisplay();
#endregion
#region Internal Implementation
/// <summary>
/// Returns ElementStyleDisplayInfo class that provides information for ElementStyle rendering.
/// </summary>
/// <param name="style">Reference to style.</param>
/// <param name="g">Reference to graphics object.</param>
/// <param name="bounds">Style bounds</param>
/// <returns>New instance of ElementStyleDisplayInfo</returns>
protected ElementStyleDisplayInfo GetElementStyleDisplayInfo(ElementStyle style, Graphics g, Rectangle bounds)
{
m_ElementStyleDisplayInfo.Style=style;
m_ElementStyleDisplayInfo.Graphics=g;
m_ElementStyleDisplayInfo.Bounds=bounds;
return m_ElementStyleDisplayInfo;
}
private NodeConnectorDisplay GetConnectorDisplay(NodeConnector c)
{
NodeConnectorDisplay d=null;
if(c==null)
return null;
switch(c.ConnectorType)
{
case eNodeConnectorType.Line:
{
if(m_LineConnectorDisplay==null)
m_LineConnectorDisplay=new LineConnectorDisplay();
d=m_LineConnectorDisplay;
break;
}
}
return d;
}
/// <summary>
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeBackground(NodeRendererEventArgs e)
{
ElementStyleDisplayInfo di = GetElementStyleDisplayInfo(e.Style, e.Graphics, e.NodeBounds);
ElementStyleDisplay.Paint(di);
base.DrawNodeBackground(e);
}
/// <summary>
/// Draws node expand part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeExpandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
NodeExpandDisplay expandDisplay = GetExpandDisplay(e.ExpandButtonType);
expandDisplay.ColorTable = this.ColorTable;
expandDisplay.DrawExpandButton(e);
expandDisplay.ColorTable = null;
base.DrawNodeExpandPart(e);
}
private NodeExpandDisplay GetExpandDisplay(eExpandButtonType e)
{
NodeExpandDisplay d=null;
switch(e)
{
case eExpandButtonType.Rectangle:
d=m_NodeExpandRectDisplay;
break;
case eExpandButtonType.Triangle:
d = m_NodeExpandTriangleDisplay;
break;
case eExpandButtonType.Ellipse:
d = m_NodeExpandEllipseDisplay;
break;
case eExpandButtonType.Image:
d= m_NodeExpandImageDisplay;
break;
}
return d;
}
///// <summary>
///// Draws node command part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
///// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeCommandPart method so events can occur.
///// </summary>
///// <param name="e">Information provided for rendering.</param>
//public override void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e)
//{
// m_NodeCommandDisplay.DrawCommandButton(e);
// base.DrawNodeCommandPart(e);
//}
/// <summary>
/// Draws cell background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellBackground(NodeCellRendererEventArgs e)
{
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.CellBounds));
ElementStyleDisplay.Paint(di);
base.DrawCellBackground(e);
}
/// <summary>
/// Draws cell check box. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellCheckBox method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellCheckBox(NodeCellRendererEventArgs e)
{
CellDisplay.CheckBoxPainter = m_CheckBoxPainter;
if (Office2007ColorTable != null)
CellDisplay.ColorTable = Office2007ColorTable.CheckBoxItem;
CellDisplay.PaintCellCheckBox(e);
base.DrawCellCheckBox(e);
CellDisplay.CheckBoxPainter = null;
}
/// <summary>
/// Draws cell image. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellImage method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellImage(NodeCellRendererEventArgs e)
{
CellDisplay.PaintCellImage(e);
base.DrawCellImage(e);
}
/// <summary>
/// Draws cell text. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellText method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellText(NodeCellRendererEventArgs e)
{
CellDisplay.PaintText(e);
base.DrawCellText(e);
}
/// <summary>
/// Draws selection for SelectedNode. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderSelection method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawSelection(SelectionRendererEventArgs e)
{
m_SelectionDisplay.SelectionColors = ColorTable.Selection;
m_SelectionDisplay.PaintSelection(e);
base.DrawSelection(e);
}
/// <summary>
/// Draws hot-tracking marker for mouse over node. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderHotTracking method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawHotTracking(SelectionRendererEventArgs e)
{
m_SelectionDisplay.SelectionColors = ColorTable.Selection;
m_SelectionDisplay.PaintHotTracking(e);
base.DrawHotTracking(e);
}
/// <summary>
/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawConnector(ConnectorRendererEventArgs e)
{
NodeConnectorDisplay display = GetConnectorDisplay(e.NodeConnector);
if(display!=null)
display.DrawConnector(e);
base.DrawConnector(e);
}
/// <summary>
/// Draws the tree background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTreeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawTreeBackground(TreeBackgroundRendererEventArgs e)
{
AdvTree tree = e.AdvTree;
Graphics g = e.Graphics;
if(!tree.BackColor.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(tree.BackColor))
g.FillRectangle(brush,tree.DisplayRectangle);
}
ElementStyleDisplayInfo info=new ElementStyleDisplayInfo();
info.Bounds=tree.DisplayRectangle;
info.Graphics=g;
info.Style=tree.BackgroundStyle;
ElementStyleDisplay.Paint(info);
base.DrawTreeBackground (e);
}
/// <summary>
/// Draws the drag &amp; drop marker that indicates the insertion point for the node. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderDragDropMarker method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawDragDropMarker(DragDropMarkerRendererEventArgs e)
{
m_DragDropMarkerDisplay.MarkerColor = this.ColorTable.DragDropMarker;
m_DragDropMarkerDisplay.DrawMarker(e);
base.DrawDragDropMarker(e);
}
/// <summary>
/// Draws the column header. If you need to provide custom rendering this is the method that you should override in your custom renderer. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderColumnHeader method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawColumnHeader(ColumnHeaderRendererEventArgs e)
{
ElementStyleDisplayInfo di = GetElementStyleDisplayInfo(e.Style, e.Graphics, e.Bounds);
m_ColumnHeaderDisplay.DrawColumnHeader(e, di);
base.DrawColumnHeader(e);
}
/// <summary>
/// Draws node group line when in tile view. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTileGroupLine method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawTileGroupLine(NodeRendererEventArgs e)
{
_GroupLineDisplay.DrawGroupLine(e);
OnRenderTileGroupLine(e);
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
using System;
using System.Text;
using DevComponents.WinForms.Drawing;
using System.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Defines the color table for tree selection.
/// </summary>
public class SelectionColorTable
{
/// <summary>
/// Gets or sets the outer border for the selection.
/// </summary>
public Border Border = null;
/// <summary>
/// Gets or sets the outer border corner radius.
/// </summary>
public int BorderCornerRadius = 0;
/// <summary>
/// Gets or sets the inner border for the selection.
/// </summary>
public Border InnerBorder = null;
/// <summary>
/// Gets or sets the selection fill.
/// </summary>
public Fill Fill = null;
/// <summary>
/// Gets or sets the selection text color.
/// </summary>
public Color TextColor = Color.Empty;
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Drawing;
namespace DevComponents.AdvTree
{
/// <summary>
/// Data form RenderSelection event.
/// </summary>
public class SelectionRendererEventArgs : EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to selected Node object.
/// </summary>
public DevComponents.AdvTree.Node Node=null;
/// <summary>
/// Gets or sets the selection bounds.
/// </summary>
public Rectangle Bounds=Rectangle.Empty;
/// <summary>
/// Gets or sets the node selection box style.
/// </summary>
public eSelectionStyle SelectionBoxStyle = eSelectionStyle.HighlightCells;
/// <summary>
/// Gets or sets whether tree control is active, focused.
/// </summary>
public bool TreeActive = false;
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Provides data for tree background rendering events.
/// </summary>
public class TreeBackgroundRendererEventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas tree background is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to AdvTree control.
/// </summary>
public AdvTree AdvTree = null;
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
public TreeBackgroundRendererEventArgs(Graphics g, AdvTree tree)
{
this.Graphics = g;
this.AdvTree = tree;
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Text;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Defines the Tree color table.
/// </summary>
[ToolboxItem(false)]
public class TreeColorTable : Component
{
#region Internal Implementation
/// <summary>
/// Gets or sets the color table used for the node selection display.
/// </summary>
public TreeSelectionColors Selection = new TreeSelectionColors();
/// <summary>
/// Gets or sets the color for node drag &amp; drop marker.
/// </summary>
public Color DragDropMarker = Color.Black;
/// <summary>
/// Gets or sets the color of tree expand button type of rectangle.
/// </summary>
public TreeExpandColorTable ExpandRectangle = new TreeExpandColorTable();
/// <summary>
/// Gets or sets the color of tree expand button type of Ellipse.
/// </summary>
public TreeExpandColorTable ExpandEllipse = new TreeExpandColorTable();
/// <summary>
/// Gets or sets the color of tree expand button type of Triangle.
/// </summary>
public TreeExpandColorTable ExpandTriangle = new TreeExpandColorTable();
/// <summary>
/// Gets or sets the color for tree grid lines.
/// </summary>
public Color GridLines = Color.Empty;
/// <summary>
/// Gets or sets the color of the column sort indicator which is rendered on columns when sorted.
/// </summary>
public Color ColumnSortIndicatorColor = Color.Gray;
#endregion
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Text;
using DevComponents.WinForms.Drawing;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Defines the color table for node expand button.
/// </summary>
public class TreeExpandColorTable
{
/// <summary>
/// Gets or sets the border for the expand button which expands the node.
/// </summary>
public Border ExpandBorder = null;
/// <summary>
/// Gets or sets the expand button fill for button that expands the node.
/// </summary>
public Fill ExpandFill = null;
/// <summary>
/// Gets or sets the expand button foreground for button that expands the node.
/// </summary>
public Fill ExpandForeground = null;
/// <summary>
/// Gets or sets the border for the expand button which expands the node.
/// </summary>
public Border ExpandMouseOverBorder = null;
/// <summary>
/// Gets or sets the expand button fill for button that expands the node.
/// </summary>
public Fill ExpandMouseOverFill = null;
/// <summary>
/// Gets or sets the expand button foreground for button that expands the node.
/// </summary>
public Fill ExpandMouseOverForeground = null;
/// <summary>
/// Gets or sets the border for the expand button which collapses the node.
/// </summary>
public Border CollapseBorder = null;
/// <summary>
/// Gets or sets the expand button fill for button that collapses the node.
/// </summary>
public Fill CollapseFill = null;
/// <summary>
/// Gets or sets the expand button foreground for button that expands the node.
/// </summary>
public Fill CollapseForeground = null;
/// <summary>
/// Gets or sets the border for the expand button which collapses the node.
/// </summary>
public Border CollapseMouseOverBorder = null;
/// <summary>
/// Gets or sets the expand button fill for button that collapses the node.
/// </summary>
public Fill CollapseMouseOverFill = null;
/// <summary>
/// Gets or sets the expand button foreground for button that expands the node.
/// </summary>
public Fill CollapseMouseOverForeground = null;
}
}

View File

@ -0,0 +1,386 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar.Rendering;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Represents abstract renderer class for node objects.
/// </summary>
public abstract class TreeRenderer
{
#region Events
/// <summary>
/// Occurs when node background is being drawn.
/// </summary>
public event NodeRendererEventHandler RenderNodeBackground;
/// <summary>
/// Occurs when node expand part is being drawn.
/// </summary>
public event NodeExpandPartRendererEventHandler RenderNodeExpandPart;
///// <summary>
///// Occurs when node command part is being drawn.
///// </summary>
//public event NodeCommandPartRendererEventHandler RenderNodeCommandPart;
/// <summary>
/// Occurs when cell background is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellBackground;
/// <summary>
/// Occurs when cell check-box is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellCheckBox;
/// <summary>
/// Occurs when cell image is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellImage;
/// <summary>
/// Occurs when cell text is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellText;
/// <summary>
/// Occurs when node selection marker is rendered.
/// </summary>
public event SelectionRendererEventHandler RenderSelection;
/// <summary>
/// Occurs when node hot-tracking marker is rendered.
/// </summary>
public event SelectionRendererEventHandler RenderHotTracking;
/// <summary>
/// Occurs when node connector is being drawn.
/// </summary>
public event ConnectorRendererEventHandler RenderConnector;
/// <summary>
/// Occurs when tree background is rendered.
/// </summary>
public event TreeBackgroundRendererEventHandler RenderTreeBackground;
/// <summary>
/// Occurs when drag & drop marker is rendered.
/// </summary>
public event DragDropMarkerRendererEventHandler RenderDragDropMarker;
/// <summary>
/// Renders the Column Header.
/// </summary>
public event ColumnHeaderRendererEventHandler RenderColumnHeader;
/// <summary>
/// Occurs when node group line is being rendered while control is in tile view.
/// </summary>
public event NodeRendererEventHandler RenderTileGroupLine;
#endregion
#region Private Variables
#endregion
#region Constructor
public TreeRenderer()
{
}
#endregion
#region Internal Implementation
/// <summary>
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawNodeBackground(NodeRendererEventArgs e)
{
OnRenderNodeBackground(e);
}
/// <summary>
/// Raises RenderNodeBackground event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected virtual void OnRenderNodeBackground(NodeRendererEventArgs e)
{
if(RenderNodeBackground!=null)
RenderNodeBackground(this,e);
}
/// <summary>
/// Draws node expand part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeExpandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
OnRenderNodeExpandPart(e);
}
/// <summary>
/// Raises RenderNodeExpandPart event.
/// </summary>
/// <param name="e"></param>
protected virtual void OnRenderNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
if(RenderNodeExpandPart!=null)
RenderNodeExpandPart(this,e);
}
///// <summary>
///// Draws node command part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
///// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeCommandPart method so events can occur.
///// </summary>
///// <param name="e">Information provided for rendering.</param>
//public virtual void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e)
//{
// OnRenderNodeCommandPart(e);
//}
///// <summary>
///// Raises RenderNodeCommandPart event.
///// </summary>
///// <param name="e">Event arguments.</param>
//protected virtual void OnRenderNodeCommandPart(NodeCommandPartRendererEventArgs e)
//{
// if(RenderNodeCommandPart!=null)
// RenderNodeCommandPart(this,e);
//}
/// <summary>
/// Draws cell background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellBackground(NodeCellRendererEventArgs e)
{
OnRenderCellBackground(e);
}
/// <summary>
/// Raises RenderCellBackground event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellBackground(NodeCellRendererEventArgs e)
{
if(RenderCellBackground!=null)
RenderCellBackground(this, e);
}
/// <summary>
/// Draws cell check box. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellCheckBox method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellCheckBox(NodeCellRendererEventArgs e)
{
OnRenderCellCheckBox(e);
}
/// <summary>
/// Raises RenderCellCheckBox event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellCheckBox(NodeCellRendererEventArgs e)
{
if(RenderCellCheckBox!=null)
RenderCellCheckBox(this, e);
}
/// <summary>
/// Draws cell image. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellImage method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellImage(NodeCellRendererEventArgs e)
{
OnRenderCellImage(e);
}
/// <summary>
/// Raises RenderCellImage event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellImage(NodeCellRendererEventArgs e)
{
if(RenderCellImage!=null)
RenderCellImage(this, e);
}
/// <summary>
/// Draws cell text. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellText method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellText(NodeCellRendererEventArgs e)
{
OnRenderCellText(e);
}
/// <summary>
/// Raises RenderCellImage event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellText(NodeCellRendererEventArgs e)
{
if(RenderCellText!=null)
RenderCellText(this, e);
}
/// <summary>
/// Draws selection for SelectedNode. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderSelection method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawSelection(SelectionRendererEventArgs e)
{
OnRenderSelection(e);
}
/// <summary>
/// Raises RenderSelection event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderSelection(SelectionRendererEventArgs e)
{
if(RenderSelection!=null)
RenderSelection(this, e);
}
/// <summary>
/// Draws hot-tracking marker for mouse over node. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderHotTracking method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawHotTracking(SelectionRendererEventArgs e)
{
OnRenderHotTracking(e);
}
/// <summary>
/// Raises RenderHotTracking event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderHotTracking(SelectionRendererEventArgs e)
{
if (RenderHotTracking != null)
RenderHotTracking(this, e);
}
/// <summary>
/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawConnector(ConnectorRendererEventArgs e)
{
OnRenderConnector(e);
}
/// <summary>
/// Raises RenderConnector event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderConnector(ConnectorRendererEventArgs e)
{
if(RenderConnector!=null)
RenderConnector(this, e);
}
/// <summary>
/// Draws the tree background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTreeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawTreeBackground(TreeBackgroundRendererEventArgs e)
{
OnRenderTreeBackground(e);
}
/// <summary>
/// Raises RenderTreeBackground event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderTreeBackground(TreeBackgroundRendererEventArgs e)
{
if(RenderTreeBackground!=null)
RenderTreeBackground(this, e);
}
/// <summary>
/// Draws the drag &amp; drop marker that indicates the insertion point for the node. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderDragDropMarker method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawDragDropMarker(DragDropMarkerRendererEventArgs e)
{
OnRenderDragDropMarker(e);
}
/// <summary>
/// Raises RenderDragDropMarker event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderDragDropMarker(DragDropMarkerRendererEventArgs e)
{
if (RenderDragDropMarker != null)
RenderDragDropMarker(this, e);
}
/// <summary>
/// Draws the column header. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderColumnHeader method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawColumnHeader(ColumnHeaderRendererEventArgs e)
{
OnRenderColumnHeader(e);
}
/// <summary>
/// Raises RenderDragDropMarker event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderColumnHeader(ColumnHeaderRendererEventArgs e)
{
if (RenderColumnHeader != null)
RenderColumnHeader(this, e);
}
private TreeColorTable _ColorTable = null;
/// <summary>
/// Gets or sets the color table used by the renderer.
/// </summary>
public TreeColorTable ColorTable
{
get { return _ColorTable; }
set { _ColorTable = value; }
}
private Office2007ColorTable _Office2007ColorTable = null;
/// <summary>
/// Gets or sets the color table used by the renderer.
/// </summary>
internal Office2007ColorTable Office2007ColorTable
{
get { return _Office2007ColorTable; }
set { _Office2007ColorTable = value; }
}
/// <summary>
/// Draws node group line when in tile view. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTileGroupLine method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawTileGroupLine(NodeRendererEventArgs e)
{
OnRenderTileGroupLine(e);
}
/// <summary>
/// Raises RenderNodeBackground event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected virtual void OnRenderTileGroupLine(NodeRendererEventArgs e)
{
if (RenderTileGroupLine != null)
RenderTileGroupLine(this, e);
}
#endregion
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Text;
namespace DevComponents.AdvTree.Display
{
/// <summary>
/// Defines the color table for tree selection.
/// </summary>
public class TreeSelectionColors
{
/// <summary>
/// Gets or sets the color table for FullRowSelect selection type.
/// </summary>
public SelectionColorTable FullRowSelect = null;
/// <summary>
/// Gets or sets the color table for FullRowSelect selection type when tree control is inactive.
/// </summary>
public SelectionColorTable FullRowSelectInactive = null;
/// <summary>
/// Gets or sets the color table for HighlightCells selection type.
/// </summary>
public SelectionColorTable HighlightCells = null;
/// <summary>
/// Gets or sets the color table for HighlightCells selection type when tree control is inactive.
/// </summary>
public SelectionColorTable HighlightCellsInactive = null;
/// <summary>
/// Gets or sets the color table for NodeMarker selection type.
/// </summary>
public SelectionColorTable NodeMarker = null;
/// <summary>
/// Gets or sets the color table for NodeMarker selection type when tree control is inactive.
/// </summary>
public SelectionColorTable NodeMarkerInactive = null;
/// <summary>
/// Gets or sets the color table used for node hot-tracking.
/// </summary>
public SelectionColorTable NodeHotTracking = null;
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Text;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.WinForms.Drawing
{
[ToolboxItem(false)]
public abstract class Border : Component
{
#region Internal Implementation
/// <summary>
/// Creates the pen for the border.
/// </summary>
/// <returns>Returns pen or null if pen cannot be created.</returns>
public abstract Pen CreatePen();
internal int _Width = 0;
/// <summary>
/// Gets or sets the border width. Default value is 0.
/// </summary>
[DefaultValue(0), Description("Indicates border width.")]
public int Width
{
get { return _Width; }
set
{
_Width = value;
}
}
internal static Rectangle Deflate(Rectangle bounds, Border border)
{
if (border == null) return bounds;
bounds.Inflate(-border.Width, -border.Width);
return bounds;
}
#endregion
}
}

View File

@ -0,0 +1,234 @@
using System;
using System.Collections;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
namespace DevComponents.WinForms.Drawing
{
/// <summary>
/// Represents Collection for the ColorStop objects.
/// </summary>
public class ColorBlendCollection : CollectionBase
{
#region Private Variables
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the class.</summary>
public ColorBlendCollection() { }
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="item">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(ColorStop item)
{
return List.Add(item);
}
/// <summary>
/// Adds array of new objects to the collection.
/// </summary>
/// <param name="items">Array of object to add.</param>
public void AddRange(ColorStop[] items)
{
foreach (ColorStop item in items)
this.Add(item);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public ColorStop this[int index]
{
get { return (ColorStop)(List[index]); }
set { List[index] = value; }
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, ColorStop value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(ColorStop value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(ColorStop value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(ColorStop value)
{
List.Remove(value);
}
//protected override void OnRemoveComplete(int index,object value)
//{
// base.OnRemoveComplete(index,value);
// ColorStop me=value as ColorStop;
//}
//protected override void OnInsertComplete(int index,object value)
//{
// base.OnInsertComplete(index,value);
// ColorStop me=value as ColorStop;
//}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(ColorStop[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColorStop array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(ColorStop[] array)
{
List.CopyTo(array, 0);
}
/// <summary>
/// Creates ColorBlend object based on the members of the collection. ColorBlend object will be valid only if all members of the collection
/// represents relative/percentage based color blends.
/// </summary>
/// <returns></returns>
public ColorBlend GetColorBlend()
{
ColorBlend blend = new ColorBlend();
Color[] colors = new Color[this.Count];
float[] positions = new float[this.Count];
for (int i = 0; i < this.Count; i++)
{
ColorStop b = this[i];
colors[i] = b.Color;
positions[i] = b.Position;
}
blend.Colors = colors;
blend.Positions = positions;
return blend;
}
/// <summary>
/// Adds the ColorStop objects from the collection.
/// </summary>
/// <param name="col">Collection to copy objects from</param>
public void CopyFrom(ColorBlendCollection col)
{
foreach (ColorStop b in col)
this.Add(b);
}
internal eColorStopType GetBlendType()
{
ColorBlendCollection c = this;
if (c.Count <= 1)
return eColorStopType.Invalid;
eColorStopType t = eColorStopType.Invalid;
foreach (ColorStop b in c)
{
if (b.Position == 0 || b.Position == 1f)
continue;
if (b.Position <= 1f)
{
if (t == eColorStopType.Invalid)
t = eColorStopType.Relative;
else if (t == eColorStopType.Absolute)
{
t = eColorStopType.Invalid;
break;
}
}
else
{
if (t == eColorStopType.Invalid)
t = eColorStopType.Absolute;
else if (t == eColorStopType.Relative)
{
t = eColorStopType.Invalid;
break;
}
}
}
if (c.Count == 2 && c[0].Position == 0f && c[1].Position == 1f)
return eColorStopType.Relative;
if (t == eColorStopType.Invalid)
return t;
if (t == eColorStopType.Relative && c[0].Position != 0f && c[c.Count - 1].Position != 1f)
return eColorStopType.Invalid;
else if (t == eColorStopType.Absolute && ((c.Count / 2) * 2 != c.Count))
return eColorStopType.Invalid;
return t;
}
///// <summary>
///// Initializes the collection with the two color blend.
///// </summary>
///// <param name="collection">Collection to initialize.</param>
///// <param name="backColor1">Start color.</param>
///// <param name="backColor2">End color.</param>
//public static void InitializeCollection(ColorBlendCollection collection, int backColor1, int backColor2)
//{
// InitializeCollection(collection, ColorScheme.GetColor(backColor1), ColorScheme.GetColor(backColor2));
//}
/// <summary>
/// Initializes the collection with the two color blend.
/// </summary>
/// <param name="collection">Collection to initialize.</param>
/// <param name="backColor1">Start color.</param>
/// <param name="backColor2">End color.</param>
public static void InitializeCollection(ColorBlendCollection collection, Color backColor1, Color backColor2)
{
collection.Clear();
collection.Add(new ColorStop(backColor1, 0f));
collection.Add(new ColorStop(backColor2, 1f));
}
#endregion
}
internal enum eColorStopType
{
Invalid,
Relative,
Absolute
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.WinForms.Drawing
{
/// <summary>
/// Defines single color blend point for the multicolor gradient fills.
/// </summary>
[ToolboxItem(false), DesignTimeVisible(false), TypeConverter(typeof(ColorStopConverter))]
public class ColorStop
{
#region Private Variables
private Color _Color = Color.Empty;
private float _Position = 0;
#endregion
#region Internal Implementation
/// <summary>
/// Creates new instance of the class. When defining multicolor gradient blends and using the percentage positions the positions created
/// must start with 0f and end with 1f.
/// </summary>
public ColorStop() { }
/// <summary>
/// Creates new instance of the class and initialize it with default values.
/// </summary>
public ColorStop(Color color, float position)
{
_Color = color;
_Position = position;
}
///// <summary>
///// Creates new instance of the class and initialize it with default values.
///// </summary>
//public ColorStop(int color, float position)
//{
// _Color = ColorScheme.GetColor(color);
// _Position = position;
//}
/// <summary>
/// Gets or sets Color to use in multicolor gradient blend at specified position.
/// </summary>
[Browsable(true), Description("Indicates the Color to use in multicolor gradient blend at specified position.")]
public Color Color
{
get { return _Color; }
set
{
_Color = value;
OnColorBlendChanged();
}
}
private bool ShouldSerializeColor()
{
return !_Color.IsEmpty;
}
/// <summary>
/// Gets or sets the color position in multicolor gradient blend. Values less or equal to 1 are used as percentage specifing percentages of distance along the gradient line.
/// Values greater than 1 are used as absolute pixel values of distance along the gradient line.
/// </summary>
[Browsable(true), DefaultValue(0f), Description("")]
public float Position
{
get { return _Position; }
set
{
_Position = value;
OnColorBlendChanged();
}
}
private void OnColorBlendChanged()
{
}
#endregion
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;
using System.Drawing;
namespace DevComponents.WinForms.Drawing
{
/// <summary>
/// Represents BackgroundColorBlend object converter.
/// </summary>
public class ColorStopConverter : TypeConverter
{
public ColorStopConverter() { }
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == null)
throw new ArgumentNullException("destinationType");
if ((destinationType == typeof(InstanceDescriptor)) && (value is ColorStop))
{
ColorStop doc = (ColorStop)value;
Type[] constructorParams = null;
MemberInfo constructorMemberInfo = null;
object[] constructorValues = null;
constructorParams = new Type[2] { typeof(Color), typeof(float) };
constructorMemberInfo = typeof(ColorStop).GetConstructor(constructorParams);
constructorValues = new object[2] { doc.Color, doc.Position };
if (constructorMemberInfo != null)
{
return new InstanceDescriptor(constructorMemberInfo, constructorValues);
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}

View File

@ -0,0 +1,258 @@
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Globalization;
using System.ComponentModel.Design.Serialization;
namespace DevComponents.WinForms.Drawing
{
[StructLayout(LayoutKind.Sequential), TypeConverter(typeof(CornerRadiusConverter))]
public struct CornerRadius
#if FRAMEWORK20
: IEquatable<CornerRadius>
#endif
{
#region Private Variables
private int _TopLeft;
private int _topRight;
private int _bottomLeft;
private int _bottomRight;
#endregion
#region Constructor
public CornerRadius(int uniformRadius)
{
this._TopLeft = this._topRight = this._bottomLeft = this._bottomRight = uniformRadius;
}
public CornerRadius(int topLeft, int topRight, int bottomRight, int bottomLeft)
{
this._TopLeft = topLeft;
this._topRight = topRight;
this._bottomRight = bottomRight;
this._bottomLeft = bottomLeft;
}
#endregion
#region Internal Implementation
public override bool Equals(object obj)
{
if (obj is CornerRadius)
{
CornerRadius radius = (CornerRadius)obj;
return (this == radius);
}
return false;
}
public bool Equals(CornerRadius cornerRadius)
{
return (this == cornerRadius);
}
public override int GetHashCode()
{
return (((this._TopLeft.GetHashCode() ^ this._topRight.GetHashCode()) ^ this._bottomLeft.GetHashCode()) ^ this._bottomRight.GetHashCode());
}
public override string ToString()
{
return CornerRadiusConverter.ToString(this, CultureInfo.InvariantCulture);
}
public static bool operator ==(CornerRadius cr1, CornerRadius cr2)
{
return ((cr1._TopLeft == cr2._TopLeft) && (cr1._topRight == cr2._topRight) && (cr1._bottomRight == cr2._bottomRight) && (cr1._bottomLeft == cr2._bottomLeft));
}
public static bool operator !=(CornerRadius cr1, CornerRadius cr2)
{
return !(cr1 == cr2);
}
public int TopLeft
{
get
{
return this._TopLeft;
}
set
{
this._TopLeft = value;
}
}
public int TopRight
{
get
{
return this._topRight;
}
set
{
this._topRight = value;
}
}
public int BottomRight
{
get
{
return this._bottomRight;
}
set
{
this._bottomRight = value;
}
}
public int BottomLeft
{
get
{
return this._bottomLeft;
}
set
{
this._bottomLeft = value;
}
}
internal bool IsValid(bool allowNegative)
{
if (!allowNegative && (((this._TopLeft < 0.0) || (this._topRight < 0.0)) || ((this._bottomLeft < 0.0) || (this._bottomRight < 0.0))))
{
return false;
}
return true;
}
internal bool IsZero
{
get
{
return (_TopLeft == 0 && _topRight == 0 && _bottomRight == 0 && _bottomLeft == 0);
}
}
#endregion
}
#region CornerRadiusConverter
public class CornerRadiusConverter : TypeConverter
{
// Methods
public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType)
{
switch (Type.GetTypeCode(sourceType))
{
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
case TypeCode.String:
return true;
}
return false;
}
public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType)
{
if ((destinationType != typeof(InstanceDescriptor)) && (destinationType != typeof(string)))
{
return false;
}
return true;
}
public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object source)
{
if (source == null)
{
throw base.GetConvertFromException(source);
}
if (source is string)
{
return FromString((string)source, cultureInfo);
}
return new CornerRadius(Convert.ToInt32(source, cultureInfo));
}
public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (!(value is CornerRadius))
{
throw new ArgumentException("Unexpected parameter type", "value");
}
CornerRadius cr = (CornerRadius)value;
if (destinationType == typeof(string))
{
return ToString(cr, cultureInfo);
}
if (destinationType != typeof(InstanceDescriptor))
{
throw new ArgumentException("Cannot convert to type " + destinationType.FullName);
}
return new InstanceDescriptor(typeof(CornerRadius).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) }), new object[] { cr.TopLeft, cr.TopRight, cr.BottomRight, cr.BottomLeft });
}
internal static CornerRadius FromString(string s, CultureInfo cultureInfo)
{
string[] parsed = s.Split(GetNumericListSeparator(cultureInfo));
int[] numArray = new int[4];
for (int i = 0; i < parsed.Length; i++)
{
numArray[i] = int.Parse(parsed[i], cultureInfo);
}
int index = Math.Min(5, parsed.Length);
switch (index)
{
case 1:
return new CornerRadius(numArray[0]);
case 4:
return new CornerRadius(numArray[0], numArray[1], numArray[2], numArray[3]);
}
throw new FormatException("Invalid string corner radius");
}
internal static string ToString(CornerRadius cr, CultureInfo cultureInfo)
{
char numericListSeparator = GetNumericListSeparator(cultureInfo);
StringBuilder builder = new StringBuilder(0x40);
builder.Append(cr.TopLeft.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.TopRight.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.BottomRight.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.BottomLeft.ToString(cultureInfo));
return builder.ToString();
}
internal static char GetNumericListSeparator(IFormatProvider provider)
{
char ch = ',';
NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
if ((instance.NumberDecimalSeparator.Length > 0) && (ch == instance.NumberDecimalSeparator[0]))
{
ch = ';';
}
return ch;
}
}
#endregion
}

View File

@ -0,0 +1,27 @@
using System;
using System.Text;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.WinForms.Drawing
{
[ToolboxItem(false)]
public abstract class Fill : Component
{
#region Internal Implementation
/// <summary>
/// Creates the brush for fill.
/// </summary>
/// <param name="bounds">Bounds for the brush</param>
/// <returns>Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush.</returns>
public abstract Brush CreateBrush(Rectangle bounds);
/// <summary>
/// Creates a pen based on fill parameters.
/// </summary>
/// <param name="width">Width of the pen to create</param>
/// <returns>new instance of pen or null if pen cannot be created.</returns>
public abstract Pen CreatePen(int width);
#endregion
}
}

View File

@ -0,0 +1,179 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;
namespace DevComponents.WinForms.Drawing
{
public class GradientFill : Fill
{
#region Constructor
/// <summary>
/// Initializes a new instance of the GradientFill class.
/// </summary>
public GradientFill()
{
}
/// <summary>
/// Initializes a new instance of the GradientFill class.
/// </summary>
/// <param name="color1"></param>
/// <param name="color2"></param>
public GradientFill(Color color1, Color color2)
{
_Color1 = color1;
_Color2 = color2;
}
/// <summary>
/// Initializes a new instance of the GradientFill class.
/// </summary>
/// <param name="color1"></param>
/// <param name="color2"></param>
/// <param name="angle"></param>
public GradientFill(Color color1, Color color2, float angle)
{
_Color1 = color1;
_Color2 = color2;
_Angle = angle;
}
/// <summary>
/// Initializes a new instance of the GradientFill class.
/// </summary>
/// <param name="interpolationColors"></param>
public GradientFill(ColorStop[] interpolationColors)
{
_InterpolationColors.AddRange(interpolationColors);
}
/// <summary>
/// Initializes a new instance of the GradientFill class.
/// </summary>
/// <param name="interpolationColors"></param>
public GradientFill(ColorStop[] interpolationColors, int angle)
{
_InterpolationColors.AddRange(interpolationColors);
_Angle = angle;
}
#endregion
#region Internal Implementation
/// <summary>
/// Creates the brush for fill.
/// </summary>
/// <param name="bounds">Bounds for the brush</param>
/// <returns>Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush.</returns>
public override Brush CreateBrush(Rectangle bounds)
{
if (_Color1.IsEmpty && _Color2.IsEmpty && _InterpolationColors.Count == 0 || bounds.Width < 1 || bounds.Height < 1) return null;
LinearGradientBrush brush=new LinearGradientBrush(bounds, _Color1, _Color2, _Angle);
if (_InterpolationColors.Count == 0)
return brush;
brush.InterpolationColors = _InterpolationColors.GetColorBlend();
return brush;
}
private Color _Color1 = Color.Empty;
/// <summary>
/// Gets or sets the starting gradient fill color.
/// </summary>
[Description("Indicates the fill color.")]
public Color Color1
{
get { return _Color1; }
set { _Color1 = value; }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
/// <returns>true if property should be serialized</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeColor1()
{
return !_Color1.IsEmpty;
}
/// <summary>
/// Sets the property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetColor1()
{
Color1 = Color.Empty;
}
private Color _Color2 = Color.Empty;
/// <summary>
/// Gets or sets the end gradient fill color.
/// </summary>
[Description("Indicates the fill color.")]
public Color Color2
{
get { return _Color2; }
set { _Color2 = value; }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
/// <returns>true if property should be serialized</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeColor2()
{
return !_Color2.IsEmpty;
}
/// <summary>
/// Sets the property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetColor2()
{
Color2 = Color.Empty;
}
private ColorBlendCollection _InterpolationColors = new ColorBlendCollection();
/// <summary>
/// Gets the collection that defines the multicolor gradient background.
/// </summary>
/// <remarks>
/// Setting this property creates a multicolor gradient with one color at each position along the gradient line. Setting this property nullifies all previous color, position, and falloff settings for this gradient fill.
/// </remarks>
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Collection that defines the multicolor gradient background.")]
public ColorBlendCollection InterpolationColors
{
get { return _InterpolationColors; }
}
private float _Angle = 90;
/// <summary>
/// Gets or sets the gradient fill angle. Default value is 90.
/// </summary>
[DefaultValue(90), Description("Indicates gradient fill angle.")]
public float Angle
{
get { return _Angle; }
set
{
_Angle = value;
}
}
/// <summary>
/// Creates a pen based on fill parameters.
/// </summary>
/// <param name="width">Width of the pen to create</param>
/// <returns>new instance of pen or null if pen cannot be created.</returns>
public override Pen CreatePen(int width)
{
if (!_Color1.IsEmpty)
return new Pen(_Color1, width);
if (!_Color2.IsEmpty)
return new Pen(_Color2, width);
return null;
}
#endregion
}
}

View File

@ -0,0 +1,128 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using DevComponents.AdvTree;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar;
namespace DevComponents.WinForms.Drawing
{
internal class RectangleShape : Shape
{
#region Internal Implementation
/// <summary>
/// Renders rectangle on canvas.
/// </summary>
/// <param name="g">Target graphics to render shape on.</param>
/// <param name="bounds">Shape bounds.</param>
public override void Paint(Graphics g, Rectangle bounds)
{
if (bounds.Width < 2 || bounds.Height < 2 || g == null || _Fill == null && _Border == null) return;
GraphicsPath path = null;
if (!_CornerRadius.IsZero)
{
path = DisplayHelp.GetRoundedRectanglePath(bounds, _CornerRadius.TopLeft, _CornerRadius.TopRight,
_CornerRadius.BottomRight, _CornerRadius.BottomLeft);
}
if (_Fill != null)
{
Brush brush = _Fill.CreateBrush(bounds);
if (brush != null)
{
SmoothingMode sm = g.SmoothingMode;
if (brush is SolidBrush && path==null)
g.SmoothingMode = SmoothingMode.None;
if (path == null)
g.FillRectangle(brush, bounds);
else
g.FillPath(brush, path);
g.SmoothingMode = sm;
brush.Dispose();
}
}
if (_Border != null)
{
Pen pen = _Border.CreatePen();
if (pen != null)
{
if (path == null)
g.DrawRectangle(pen, bounds);
else
g.DrawPath(pen, path);
pen.Dispose();
}
}
Shape content = this.Content;
if (content != null)
{
Rectangle contentBounds = Border.Deflate(bounds, _Border);
Region oldClip = null;
if (path != null && ClipToBounds)
{
oldClip = g.Clip;
g.SetClip(path, CombineMode.Intersect);
}
content.Paint(g, contentBounds);
if (oldClip != null) g.Clip = oldClip;
}
if (path != null) path.Dispose();
}
private Border _Border;
/// <summary>
/// Gets or sets shape border.
/// </summary>
[DefaultValue(null), Description("Indicates shape border.")]
public Border Border
{
get { return _Border; }
set { _Border = value; }
}
private Fill _Fill = null;
/// <summary>
/// Gets or sets the shape fill.
/// </summary>
[DefaultValue(null), Description("Indicates shape fill")]
public Fill Fill
{
get { return _Fill; }
set { _Fill = value; }
}
private CornerRadius _CornerRadius;
/// <summary>
/// Gets or sets the CornerRadius.
/// </summary>
public CornerRadius CornerRadius
{
get { return _CornerRadius; }
set { _CornerRadius = value; }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeCornerRadius()
{
return !_CornerRadius.IsZero;
}
/// <summary>
/// Resets the property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetCornerRadius()
{
CornerRadius = new CornerRadius();
}
#endregion
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.WinForms.Drawing
{
/// <summary>
/// Defines a visual shape.
/// </summary>
internal abstract class Shape
{
#region Internal Implementation
/// <summary>
/// Renders shape on canvas.
/// </summary>
/// <param name="g">Target graphics to render shape on.</param>
/// <param name="bounds">Shape bounds.</param>
public abstract void Paint(Graphics g, Rectangle bounds);
private Shape _Content = null;
/// <summary>
/// Gets or sets the single piece of content inside of the shape.
/// </summary>
[DefaultValue(null)]
public Shape Content
{
get { return _Content; }
set { _Content = value; }
}
private bool _ClipToBounds = false;
/// <summary>
/// Gets or sets whether to clip the Content of this shape. Default value is false.
/// </summary>
[DefaultValue(false)]
public bool ClipToBounds
{
get { return _ClipToBounds; }
set
{
_ClipToBounds = value;
}
}
#endregion
}
}

View File

@ -0,0 +1,86 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.WinForms.Drawing
{
public class SolidBorder : Border
{
#region Constructor
/// <summary>
/// Initializes a new instance of the SolidBorder class.
/// </summary>
/// <param name="color"></param>
/// <param name="width"></param>
public SolidBorder(Color color, int width)
{
_Color = color;
_Width = width;
}
/// <summary>
/// Initializes a new instance of the SolidBorder class.
/// </summary>
/// <param name="color"></param>
public SolidBorder(Color color)
{
_Color = color;
}
/// <summary>
/// Initializes a new instance of the SolidBorder class.
/// </summary>
public SolidBorder()
{
}
#endregion
#region Internal Implementation
/// <summary>
/// Creates the pen for the border.
/// </summary>
/// <returns>Returns pen or null if pen cannot be created.</returns>
public override Pen CreatePen()
{
if (!CanCreatePen()) return null;
return new Pen(_Color, _Width);
}
private bool CanCreatePen()
{
return !_Color.IsEmpty && _Width > 0;
}
private Color _Color = Color.Empty;
/// <summary>
/// Gets or sets the fill color.
/// </summary>
[Description("Indicates the fill color.")]
public Color Color
{
get { return _Color; }
set { _Color = value; }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
/// <returns>true if property should be serialized</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeColor()
{
return !_Color.IsEmpty;
}
/// <summary>
/// Sets the property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetColor()
{
Color = Color.Empty;
}
#endregion
}
}

View File

@ -0,0 +1,76 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.WinForms.Drawing
{
public class SolidFill : Fill
{
#region Constructor
/// <summary>
/// Initializes a new instance of the SolidFill class.
/// </summary>
/// <param name="color"></param>
public SolidFill(Color color)
{
_Color = color;
}
/// <summary>
/// Initializes a new instance of the SolidFill class.
/// </summary>
public SolidFill()
{
}
#endregion
#region Internal Implementation
/// <summary>
/// Creates the brush for fill.
/// </summary>
/// <param name="bounds">Bounds for the brush</param>
/// <returns>Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush.</returns>
public override Brush CreateBrush(Rectangle bounds)
{
if (_Color.IsEmpty) return null;
return new SolidBrush(_Color);
}
private Color _Color = Color.Empty;
/// <summary>
/// Gets or sets the fill color.
/// </summary>
[Description("Indicates the fill color.")]
public Color Color
{
get { return _Color; }
set { _Color = value; }
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
/// <returns>true if property should be serialized</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeColor()
{
return !_Color.IsEmpty;
}
/// <summary>
/// Sets the property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetColor()
{
Color = Color.Empty;
}
public override Pen CreatePen(int width)
{
if (!_Color.IsEmpty)
return new Pen(_Color, width);
return null;
}
#endregion
}
}

View File

@ -0,0 +1,143 @@
using System;
using System.Collections;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents collection for Node objects.
/// </summary>
public class ElementStyleCollection:CollectionBase
{
#region Private Variables
private AdvTree m_TreeControl=null;
//private Hashtable m_InnerHashtable=new Hashtable();
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the object.</summary>
public ElementStyleCollection()
{
}
internal AdvTree TreeControl
{
get {return m_TreeControl;}
set {m_TreeControl=value;}
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="tab">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(ElementStyle style)
{
return List.Add(style);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public ElementStyle this[int index]
{
get {return (ElementStyle)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Returns reference to the object in collection based on it's name.
/// </summary>
public ElementStyle this[string name]
{
get
{
foreach(ElementStyle style in this.List)
{
if(style.Name==name)
return style;
}
return null;
}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, ElementStyle value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(ElementStyle value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(ElementStyle value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(ElementStyle value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
ElementStyle style=value as ElementStyle;
style.Parent=null;
//m_InnerHashtable.Remove(style.Name);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
ElementStyle style=value as ElementStyle;
if(style.Parent!=null && style.Parent!=this)
style.Parent.Remove(style);
style.Parent=this;
//m_InnerHashtable.Add(style.Name,style);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(ElementStyle[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Node array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(ElementStyle[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
}

View File

@ -0,0 +1,766 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Specifies layout of the items in AdvTree control.
/// </summary>
public enum eView
{
/// <summary>
/// Standard TreeView layout.
/// </summary>
Tree,
/// <summary>
/// ListView style tile layout.
/// </summary>
Tile
}
/// <summary>Specifies the way background image is displayed on background.</summary>
public enum eStyleBackgroundImage:int
{
/// <summary>Image is stretched to fill the background</summary>
Stretch=0,
/// <summary>Image is centered inside the background</summary>
Center=1,
/// <summary>Image is tiled inside the background</summary>
Tile=2,
/// <summary>
/// Image is drawn in top left corner of container space.
/// </summary>
TopLeft=3,
/// <summary>
/// Image is drawn in top right corner of container space.
/// </summary>
TopRight=4,
/// <summary>
/// Image is drawn in bottom left corner of container space.
/// </summary>
BottomLeft=5,
/// <summary>
/// Image is drawn in bottom right corner of container space.
/// </summary>
BottomRight=6
}
/// <summary>Indicates alignment of a part of the cell like image or check box in relation to the text.</summary>
public enum eCellPartAlignment:int
{
/// <summary>
/// Part is aligned to the left center of the text assuming left-to-right
/// orientation.
/// </summary>
NearCenter=0,
/// <summary>
/// Part is aligned to the right center of the text assuming left-to-right
/// orientation.
/// </summary>
FarCenter=1,
/// <summary>
/// Part is aligned to the top left of the text assuming left-to-right
/// orientation.
/// </summary>
NearTop=2,
/// <summary>Part is aligned above the text and centered.</summary>
CenterTop=3,
/// <summary>
/// Part is aligned to the top right of the text assuming left-to-right
/// orientation.
/// </summary>
FarTop=4,
/// <summary>
/// Part is aligned to the bottom left of the text assuming left-to-right
/// orientation.
/// </summary>
NearBottom=5,
/// <summary>Part is aligned below the text and centered.</summary>
CenterBottom=6,
/// <summary>
/// Part is aligned to the bottom right of the text assuming left-to-right
/// orientation.
/// </summary>
FarBottom=7,
/// <summary>
/// Part has default alignment that depends on the parent control view.
/// </summary>
Default = 8
}
/// <summary>
/// Specifies how to trim characters from a text that does not completely fit into a element's shape.
/// </summary>
public enum eStyleTextTrimming
{
/// <summary>
/// Specifies that the text is trimmed to the nearest character.
/// </summary>
Character=System.Drawing.StringTrimming.Character,
/// <summary>
/// Specifies that the text is trimmed to the nearest character, and an ellipsis is inserted at the end of a trimmed line.
/// </summary>
EllipsisCharacter=System.Drawing.StringTrimming.EllipsisCharacter,
/// <summary>
/// The center is removed from trimmed lines and replaced by an ellipsis. The algorithm keeps as much of the last slash-delimited segment of the line as possible.
/// </summary>
EllipsisPath=System.Drawing.StringTrimming.EllipsisPath,
/// <summary>
/// Specifies that text is trimmed to the nearest word, and an ellipsis is inserted at the end of a trimmed line.
/// </summary>
EllipsisWord=System.Drawing.StringTrimming.EllipsisWord,
/// <summary>
/// Specifies no trimming.
/// </summary>
None=System.Drawing.StringTrimming.None,
/// <summary>
/// Specifies that text is trimmed to the nearest word.
/// </summary>
Word=System.Drawing.StringTrimming.Word
}
///// <summary>
///// Specifies the border type for style element.
///// </summary>
//public enum eStyleBorderType:int
//{
// /// <summary>Indicates no border</summary>
// None,
// /// <summary>Border is a solid line</summary>
// Solid,
// /// <summary>Border is a solid dash line</summary>
// Dash,
// /// <summary>Border is solid dash-dot line</summary>
// DashDot,
// /// <summary>Border is solid dash-dot-dot line</summary>
// DashDotDot,
// /// <summary>Border consists of dots</summary>
// Dot,
// /// <summary>Etched Border</summary>
// Etched,
// /// <summary>Double Border</summary>
// Double
//}
/// <summary>
/// Indicates absolute vertical alignment of the content.
/// </summary>
public enum eVerticalAlign
{
/// <summary>
/// Content is aligned to the top
/// </summary>
Top,
/// <summary>
/// Content is aligned in the middle
/// </summary>
Middle,
/// <summary>
/// Content is aligned at the bottom
/// </summary>
Bottom
}
/// <summary>
/// Indicates absolute horizontal alignment
/// </summary>
public enum eHorizontalAlign
{
/// <summary>
/// Content is left aligned
/// </summary>
Left,
/// <summary>
/// Content is centered
/// </summary>
Center,
/// <summary>
/// Content is right aligned
/// </summary>
Right
}
/// <summary>
/// Indicates prefered node layout position on Map tree layout when node is the child node of the top-level root node.
/// </summary>
public enum eMapPosition
{
/// <summary>
/// Node is positioned based on default algorithm.
/// </summary>
Default,
/// <summary>
/// Sub-root node and all nodes after it are positioned to the left of the root.
/// </summary>
Near,
/// <summary>
/// Sub-root node and all nodes before it are positioned to the right of the root.
/// </summary>
Far
}
///// <summary>
///// Indicates corner type for the border around visual element.
///// </summary>
//public enum eCornerType
//{
// /// <summary>
// /// Specifies that corner type is inherited from parent setting.
// /// </summary>
// Inherit,
// /// <summary>
// /// Specifies square corner.
// /// </summary>
// Square,
// /// <summary>
// /// Specifies rounded corner.
// /// </summary>
// Rounded,
// /// <summary>
// /// Specifies diagonal corner.
// /// </summary>
// Diagonal
//}
/// <summary>
/// Specifies the column header visibility for the node.
/// </summary>
public enum eNodeHeaderVisibility
{
/// <summary>
/// Column header is automatically shown/hidden based on the node's position in the tree. When
/// Node is first child node i.e. with index=0 the header will be shown, otherwise header will
/// be hidden.
/// </summary>
Automatic,
/// <summary>
/// Column header is always displayed regardless of node's position.
/// </summary>
AlwaysShow,
/// <summary>
/// Column header is always hidden regardless of node's position.
/// </summary>
AlwaysHide
}
/// <summary>
/// Indicates the part of the node.
/// </summary>
public enum eNodeRectanglePart
{
/// <summary>
/// Bounds of complete node content except expand button. This also includes the child node bounds if node is expanded.
/// </summary>
NodeContentBounds,
/// <summary>
/// Bounds of the expand button which collapses/expands the node.
/// </summary>
ExpandBounds,
/// <summary>
/// Hit test bounds of the expand button which collapses/expands the node used by mouse routines to trigger node expansion/collapse.
/// </summary>
ExpandHitTestBounds,
/// <summary>
/// Bounds of all child nodes of give node.
/// </summary>
ChildNodeBounds,
/// <summary>
/// Bounds for cells inside a node.
/// </summary>
CellsBounds,
/// <summary>
/// Complete node bounds including expand button.
/// </summary>
NodeBounds,
/// <summary>
/// Bounds of the command button.
/// </summary>
CommandBounds,
/// <summary>
/// Bounds of child node columns if node has columns defined.
/// </summary>
ColumnsBounds
}
/// <summary>
/// Indicates the part of the cell.
/// </summary>
internal enum eCellRectanglePart
{
/// <summary>
/// Bounds of check box or Rectangle.Empty if there is no check-box.
/// </summary>
CheckBoxBounds,
/// <summary>
/// Bounds of image inside the cell or Rectangle.Empty if there is no image.
/// </summary>
ImageBounds,
/// <summary>
/// Text bounds inside of cell.
/// </summary>
TextBounds,
/// <summary>
/// Cell bounds
/// </summary>
CellBounds
}
/// <summary>
/// Indicates part of the node mouse is placed over.
/// </summary>
internal enum eMouseOverNodePart
{
/// <summary>
/// Mouse is not over any node part.
/// </summary>
None,
/// <summary>
/// Mouse is placed over the node.
/// </summary>
Node,
/// <summary>
/// Mouse is placed over node expand button.
/// </summary>
Expand,
/// <summary>
/// Mouse is placed over the cell.
/// </summary>
Cell,
/// <summary>
/// Mouse is placed over the command button.
/// </summary>
Command
}
///// <summary>
///// Indicates white-space part of the style.
///// </summary>
//[Flags()]
//public enum eSpacePart
//{
// /// <summary>
// /// Represents style padding.
// /// </summary>
// Padding=1,
// /// <summary>
// /// Represents style border.
// /// </summary>
// Border=2,
// /// <summary>
// /// Represents style margin.
// /// </summary>
// Margin=4
//}
///// <summary>
///// Indicates the style side.
///// </summary>
//public enum eStyleSide
//{
// /// <summary>
// /// Specifies left side of the style.
// /// </summary>
// Left,
// /// <summary>
// /// Specifies right side of the style.
// /// </summary>
// Right,
// /// <summary>
// /// Specifies top side of the style.
// /// </summary>
// Top,
// /// <summary>
// /// Specifies bottom side of the style.
// /// </summary>
// Bottom
//}
/// <summary>
/// Indicates the visibility of node expand part which allows user to expand/collaps node.
/// </summary>
public enum eNodeExpandVisibility
{
/// <summary>
/// Default setting which indicates that when node has child nodes expand part is visible otherwise it is hidden.
/// </summary>
Auto,
/// <summary>
/// Expand part is always visible regardless of whether child nodes are present or not.
/// </summary>
Visible,
/// <summary>
/// Expand part is always hidden regardless of whether child nodes are present or not.
/// </summary>
Hidden
}
/// <summary>
/// Specifies the action that raised a AdvTreeEventArgs event
/// </summary>
public enum eTreeAction
{
/// <summary>
/// The event was caused by a keystroke.
/// </summary>
Keyboard,
/// <summary>
/// The event was caused by a mouse operation.
/// </summary>
Mouse,
/// <summary>
/// The event was caused by the Node collapsing.
/// </summary>
Collapse,
/// <summary>
/// The event was caused by the Node expanding.
/// </summary>
Expand,
/// <summary>
/// The event is caused programmatically from user code.
/// </summary>
Code
}
/// <summary>
/// Specifies node connector type. Node connector is the type of the line/connection that is drawn to connect child node to it's parent node.
/// </summary>
public enum eNodeConnectorType
{
///// <summary>
///// Curved line connector type.
///// </summary>
//Curve,
/// <summary>
/// Straight line connector type.
/// </summary>
Line
}
///// <summary>
///// Specifies the cap style with which the connector line will start or end.
///// </summary>
//public enum eConnectorCap
//{
// /// <summary>
// /// Specifies no cap.
// /// </summary>
// None,
// /// <summary>
// /// Round cap type.
// /// </summary>
// Ellipse,
// /// <summary>
// /// Arrow cap type.
// /// </summary>
// Arrow
//}
/// <summary>
/// Specifies the layout type used to position the cells within the nodes.
/// </summary>
public enum eCellLayout
{
/// <summary>
/// Specifies that default setting is to be used for cell layout. Default is Horizontal. When set to default on the Node, setting from Tree control is used.
/// </summary>
Default,
/// <summary>Horizontal layout positions the cells horizontally next to each other.</summary>
Horizontal,
/// <summary>
/// Vertical layout positions cell vertically on top of each other.
/// </summary>
Vertical
}
/// <summary>
/// Specifies the layout type used to position the parts of the cell like image, checkbox and text.
/// </summary>
public enum eCellPartLayout
{
/// <summary>
/// Specifies that default setting is to be used for cell parts layout. Default is Horizontal. When set to default on the Cell, setting from Tree control is used.
/// </summary>
Default,
/// <summary>Horizontal layout positions the parts of the cell horizontally next to each other.</summary>
Horizontal,
/// <summary>
/// Vertical layout positions parts of the cell vertically on top of each other.
/// </summary>
Vertical
}
/// <summary>
/// Specifies the color scheme loaded by ColorScheme object.
/// </summary>
public enum eColorSchemeStyle
{
/// <summary>
/// Indicates Office 2003 like color scheme.
/// </summary>
Office2003,
/// <summary>
/// Indicates VS.NET 2005 like color scheme.
/// </summary>
VS2005,
/// <summary>
/// Indicates Office 2007 like color scheme.
/// </summary>
Office2007
}
/// <summary>
/// Specifies the currently selected system color scheme if running on Windows XP.
/// </summary>
internal enum eWinXPColorScheme
{
/// <summary>
/// Color scheme cannot be determined.
/// </summary>
Undetermined,
/// <summary>
/// Blue color scheme.
/// </summary>
Blue,
/// <summary>
/// Olive green color scheme.
/// </summary>
OliveGreen,
/// <summary>
/// Silver color scheme.
/// </summary>
Silver
}
/// <summary>
/// Specifies the flow of diagram layout related to the root node.
/// </summary>
public enum eDiagramFlow
{
/// <summary>
/// Nodes are positioned from left to right with root node being the left-most node.
/// </summary>
LeftToRight,
/// <summary>
/// Nodes are positioned from right to left with root node being the right-most
/// node.
/// </summary>
RightToLeft,
/// <summary>
/// Nodes are positioned from top to bottom with root node being the top node.
/// </summary>
TopToBottom,
/// <summary>
/// Nodes are positioned from bottom to top with root node being bottom node.
/// </summary>
BottomToTop
}
/// <summary>
/// Specifies the flow of the map layout.
/// </summary>
public enum eMapFlow
{
/// <summary>
/// Nodes are arranged around the root node.
/// </summary>
Spread,
/// <summary>
/// Nodes are arranged from below the root node.
/// </summary>
TopToBottom,
/// <summary>
/// Nodes are arranged above the root node.
/// </summary>
BottomToTop,
/// <summary>
/// Nodes are arranged to the right of the root node.
/// </summary>
LeftToRight,
/// <summary>
/// Nodes are arranged to the left of the root node.
/// </summary>
RightToLeft
}
/// <summary>
/// Specifies the type of the expand button.
/// </summary>
public enum eExpandButtonType
{
/// <summary>
/// Indicates elliptical expand button.
/// </summary>
Ellipse,
/// <summary>
/// Indicates rectangular expand button.
/// </summary>
Rectangle,
/// <summary>
/// Indicates that images are used for expand button.
/// </summary>
Image,
/// <summary>
/// Indicates the Windows Vista style expand button.
/// </summary>
Triangle
}
/// <summary>
/// Specifies the visual style for the tree control.
/// </summary>
public enum eVisualStyle
{
/// <summary>
/// Indicates default visual style.
/// </summary>
Default
}
/// <summary>
/// Specifies the layout type for the nodes.
/// </summary>
public enum eNodeLayout
{
/// <summary>
/// Nodes are arranged around root node in map format.
/// </summary>
Map,
/// <summary>
/// Nodes are arranged from left-to-right in diagram format.
/// </summary>
Diagram
}
/// <summary>
/// Specifies renderer type used to render nodes.
/// </summary>
public enum eNodeRenderMode
{
/// <summary>
/// Specifies default renderer which allows most customization through AdvTree
/// properties. Default renderer integrates with the Style architecture to provide
/// customization on renderer behavior.
/// </summary>
Default,
///// <summary>
///// <para>Specifies professional renderer. Professional renderer is custom renderer
///// which does not rely on Style architecture for customization of renderer appearance
///// since it provides much richer appearance than Default renderer.</para>
///// <para>Professional renderer colors can be controls through
///// NodeProfessionalColorTable object which is exposed by
///// NodeProfessionalRenderer.ColorTable property.</para>
///// </summary>
//Professional,
/// <summary>
/// Specifies that custom renderer is used. When set you must also set NodeRenderer
/// to renderer you want to use.
/// </summary>
Custom
}
/// <summary>
/// Specifies the node selection style.
/// </summary>
public enum eSelectionStyle
{
/// <summary>
/// Node selector highlights the complete node row when node is selected.
/// </summary>
FullRowSelect,
/// <summary>
/// Node selector draws the rectangle that highlights the node content. Appearance similar to system tree view in Windows Vista.
/// </summary>
HighlightCells,
/// <summary>
/// Node selector draws hollow selection rectangle around the node.
/// </summary>
NodeMarker,
}
/// <summary>
/// Specifies the rule for multi-node selection.
/// </summary>
public enum eMultiSelectRule
{
/// <summary>
/// Allows multiple selection of nodes with same parent node only.
/// </summary>
SameParent,
/// <summary>
/// Allows multiple selection of any node.
/// </summary>
AnyNode
}
/// <summary>
/// Gets or sets the image alignment inside of column header.
/// </summary>
public enum eColumnImageAlignment
{
/// <summary>
/// Image is left aligned.
/// </summary>
Left,
/// <summary>
/// Image is right aligned.
/// </summary>
Right
}
/// <summary>
/// Specifies the editor type used when cell is edited.
/// </summary>
public enum eCellEditorType
{
/// <summary>
/// Indicates default, text based editor.
/// </summary>
Default,
/// <summary>
/// Indicates that Integer numeric editor will be used for editing the value of the cell or column.
/// </summary>
NumericInteger,
/// <summary>
/// Indicates that Double numeric editor will be used for editing the value of the cell or column.
/// </summary>
NumericDouble,
/// <summary>
/// Indicates that Currency numeric editor will be used for editing the value of the cell or column.
/// </summary>
NumericCurrency,
/// <summary>
/// Indicates that date editor will be used for editing the value of the cell or column.
/// </summary>
Date,
/// <summary>
/// Indicates that time editor will be used for editing the value of the cell or column.
/// </summary>
Time,
/// <summary>
/// Indicates that date and time editor will be used for editing the value of the cell or column.
/// </summary>
DateTime,
/// <summary>
/// Indicates that cell will use custom editor that you provide by handling AdvTree.ProvideCustomCellEditor event.
/// </summary>
Custom
}
/// <summary>
/// Specifies the sort direction for the column header.
/// </summary>
public enum eSortDirection
{
/// <summary>
/// No sort is specified.
/// </summary>
None,
/// <summary>
/// Ascending sorting is in effect, i.e. A-Z
/// </summary>
Ascending,
/// <summary>
/// Descending sorting is in effect, i.e. Z-A
/// </summary>
Descending
}
}

View File

@ -0,0 +1,98 @@
using System;
using DevComponents.AdvTree.Display;
namespace DevComponents.AdvTree
{
/// <summary>
/// Defines the delegate for AdvTree cell based action events.
/// </summary>
public delegate void AdvTreeCellEventHandler(object sender, AdvTreeCellEventArgs e);
/// <summary>
/// Defines the delegate for AdvTree cell based action events.
/// </summary>
public delegate void AdvTreeCellCancelEventHandler(object sender, TreeCellCancelEventArgs e);
/// <summary>
/// Defines the delegate for AdvTree node based action events that can be cancelled.
/// </summary>
public delegate void AdvTreeNodeCancelEventHandler(object sender, AdvTreeNodeCancelEventArgs e);
/// <summary>
/// Defines the delegate for AdvTree node based action events.
/// </summary>
public delegate void AdvTreeNodeEventHandler(object sender, AdvTreeNodeEventArgs e);
/// <summary>
/// Defines delegate for Command button events.
/// </summary>
public delegate void CommandButtonEventHandler(object sender, CommandButtonEventArgs e);
/// <summary>
/// Defines delegate for label editing events.
/// </summary>
public delegate void CellEditEventHandler(object sender, CellEditEventArgs e);
/// <summary>
/// Defines the delegate for AdvTree node based action events.
/// </summary>
public delegate void TreeNodeCollectionEventHandler(object sender, TreeNodeCollectionEventArgs e);
/// <summary>
/// Defines the delegate for BeforeNodeDrop and AfterNodeDrop events
/// </summary>
public delegate void TreeDragDropEventHandler(object sender, TreeDragDropEventArgs e);
/// <summary>
/// Defines the delegate for NodeDragFeedback event.
/// </summary>
public delegate void TreeDragFeedbackEventHander(object sender, TreeDragFeedbackEventArgs e);
/// <summary>
/// Defines the delegate for mouse based node events
/// </summary>
public delegate void TreeNodeMouseEventHandler(object sender, TreeNodeMouseEventArgs e);
/// <summary>
/// Defines delegate for node rendering events.
/// </summary>
public delegate void NodeRendererEventHandler(object sender, NodeRendererEventArgs e);
/// <summary>
/// Defines delegate for cell rendering events.
/// </summary>
public delegate void NodeCellRendererEventHandler(object sender, NodeCellRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderExpandPart event.
/// </summary>
public delegate void NodeExpandPartRendererEventHandler(object sender, NodeExpandPartRendererEventArgs e);
///// <summary>
///// Defines delegate for RenderExpandPart event.
///// </summary>
//public delegate void NodeCommandPartRendererEventHandler(object sender, NodeCommandPartRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderExpandPart event.
/// </summary>
public delegate void SelectionRendererEventHandler(object sender, SelectionRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderConnector event.
/// </summary>
public delegate void ConnectorRendererEventHandler(object sender, ConnectorRendererEventArgs e);
/// <summary>
/// Defines delegate for TreeBackgroundRenderer events.
/// </summary>
public delegate void TreeBackgroundRendererEventHandler(object sender, TreeBackgroundRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderDragDropMarker event.
/// </summary>
public delegate void DragDropMarkerRendererEventHandler(object sender, DragDropMarkerRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderColumnHeader event.
/// </summary>
public delegate void ColumnHeaderRendererEventHandler(object sender, ColumnHeaderRendererEventArgs e);
public delegate void AdvTreeCellBeforeCheckEventHandler(object sender, AdvTreeCellBeforeCheckEventArgs e);
}

View File

@ -0,0 +1,34 @@
using System;
using System.Text;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides data for the ProvideCustomCellEditor event.
/// </summary>
public class CustomCellEditorEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the cell editor. You must set this property in your event handler to the custom
/// editor to be used for cell editing.
/// </summary>
public ICellEditControl EditControl = null;
/// <summary>
/// Gets the cell editor will be used for.
/// </summary>
public readonly Cell Cell;
/// <summary>
/// Initializes a new instance of the CustomCellEditorEventArgs class.
/// </summary>
/// <param name="cell"></param>
public CustomCellEditorEventArgs(Cell cell)
{
Cell = cell;
}
}
/// <summary>
/// Defines delegate for ProvideCustomCellEditor event.
/// </summary>
public delegate void CustomCellEditorEventHandler(object sender, CustomCellEditorEventArgs e);
}

View File

@ -0,0 +1,36 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides more information about MarkupLinkClick event.
/// </summary>
public class MarkupLinkClickEventArgs : EventArgs
{
/// <summary>
/// Gets the value of href attribute from the markup link that was clicked.
/// </summary>
public readonly string HRef = "";
/// <summary>
/// Gets the value of name attribute from the markup link that was clicked.
/// </summary>
public readonly string Name = "";
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="name">Value of name attribute.</param>
/// <param name="href">Value of href attribute.</param>
public MarkupLinkClickEventArgs(string name, string href)
{
this.HRef = href;
this.Name = name;
}
}
/// <summary>
/// Defines delegate for MarkupLinkClick event.
/// </summary>
public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e);
}

View File

@ -0,0 +1,38 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents arguments for SerializeNode event which allows you to add custom serialization data to definitions saved by control.
/// </summary>
public class SerializeNodeEventArgs : EventArgs
{
/// <summary>
/// Gets reference to the node being serialized or de-serialized.
/// </summary>
public Node Node = null;
/// <summary>
/// Gets reference to instance of XmlElement that item is serialized to or is being de-serialized from. You should not change any data directly on this element.
/// </summary>
public System.Xml.XmlElement ItemXmlElement = null;
/// <summary>
/// Gets the reference to XmlElement that you can serialize to or de-serialize any custom data from. You can add child elements or set the attributes on
/// this XmlElement when handling SerializeItem event. When handling DeserializeItem event you can load your data from this element.
/// </summary>
public System.Xml.XmlElement CustomXmlElement = null;
public SerializeNodeEventArgs(Node node, System.Xml.XmlElement itemXmlElement, System.Xml.XmlElement customXmlElement)
{
this.Node = node;
this.ItemXmlElement = itemXmlElement;
this.CustomXmlElement = customXmlElement;
}
}
/// <summary>
/// Defines delegate for SerializeItem event.
/// </summary>
public delegate void SerializeNodeEventHandler(object sender, SerializeNodeEventArgs e);
}

View File

@ -0,0 +1,40 @@
using System;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents the table header.
/// </summary>
public class HeaderDefinition
{
private string m_Name="";
private ColumnHeaderCollection m_Columns=new ColumnHeaderCollection();
/// <summary>
/// Default constructor.
/// </summary>
public HeaderDefinition()
{
}
/// <summary>
/// Gets the reference to the collection that contains the columns associated with header.
/// </summary>
[Browsable(true),Category("Columns"),Description("Gets the reference to the collection that contains the columns associated with header."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnHeaderCollection Columns
{
get {return m_Columns;}
}
/// <summary>
/// Gets or sets the name associated with this header definition.
/// </summary>
[Browsable(true),Category("Design"),Description("Indicates name associated with this header definition."),DefaultValue("")]
public string Name
{
get {return m_Name;}
set {m_Name=value;}
}
}
}

View File

@ -0,0 +1,135 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents collection for HeaderDefinition objects.
/// </summary>
public class HeadersCollection:CollectionBase
{
#region Private Variables
private AdvTree m_Parent=null;
#endregion
#region Internal Implementation
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AdvTree Parent
{
get {return m_Parent;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">HeaderDefinition that is parent of this collection.</param>
internal void SetParent(AdvTree parent)
{
m_Parent=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="ch">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(HeaderDefinition ch)
{
return List.Add(ch);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public HeaderDefinition this[int index]
{
get {return (HeaderDefinition)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, HeaderDefinition value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(HeaderDefinition value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(HeaderDefinition value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(HeaderDefinition value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(HeaderDefinition[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the HeaderDefinition array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(HeaderDefinition[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
public HeaderDefinition GetByName(string name)
{
foreach(HeaderDefinition d in this.List)
{
if(d.Name==name)
return d;
}
return null;
}
#endregion
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Specifies the notification interface that node uses to communicate status changes to it's parent tree.
/// </summary>
public interface INodeNotify
{
/// <summary>Called when Node.Expanded property has changed.</summary>
/// <param name="node">Node which Expanded property has changed.</param>
void ExpandedChanged(Node node);
/// <summary>Called before node is collapsed</summary>
/// <param name="e">Context information.</param>
void OnBeforeCollapse(AdvTreeNodeCancelEventArgs e);
/// <summary>Called before node is expanded</summary>
/// <param name="e">Context information.</param>
void OnBeforeExpand(AdvTreeNodeCancelEventArgs e);
/// <summary>Called after node is collapsed.</summary>
/// <param name="e">Context information.</param>
void OnAfterCollapse(AdvTreeNodeEventArgs e);
/// <summary>Called after node is expanded</summary>
/// <param name="e">Context information</param>
void OnAfterExpand(AdvTreeNodeEventArgs e);
}
}

View File

@ -0,0 +1,58 @@
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System;
namespace DevComponents.AdvTree.Interop
{
/// <summary>
/// Provides WinApi functions to rest of the application.
/// </summary>
internal class WinApi
{
#region API Calls Declaration
[DllImport("user32")]
private static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT tme);
[StructLayout(LayoutKind.Sequential)]
private struct TRACKMOUSEEVENT
{
public int cbSize;
public uint dwFlags;
public int dwHoverTime;
public IntPtr hwndTrack;
}
// Track Mouse Event Flags
private const uint
TME_HOVER=0x00000001,
TME_LEAVE=0x00000002,
TME_NONCLIENT=0x00000010,
TME_QUERY=0x40000000,
TME_CANCEL=0x80000000,
HOVER_DEFAULT=0xFFFFFFFF;
#endregion
#region Functions
/// <summary>
/// Resets Hoover timer for specified control.
/// </summary>
public static void ResetHover(System.Windows.Forms.Control c)
{
if (c==null || !c.IsHandleCreated)
return;
// We need to reset hover thing since it is fired only first time mouse hovers inside the window and we need it for each of our items
TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT();
tme.dwFlags = TME_QUERY;
tme.hwndTrack = c.Handle;
tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme);
TrackMouseEvent(ref tme);
tme.dwFlags = tme.dwFlags | TME_HOVER;
TrackMouseEvent(ref tme);
}
#endregion
}
}

View File

@ -0,0 +1,370 @@
using System;
using System.Windows.Forms;
using System.Drawing;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides AdvTree Keyboard handling.
/// </summary>
internal class KeyNavigation
{
public static void KeyDown(AdvTree tree, KeyEventArgs e)
{
Node node = tree.SelectedNode;
if (node != null)
{
node.InternalKeyDown(e);
if (e.Handled) return;
}
switch(e.KeyCode)
{
case Keys.Space:
{
SpaceKeyDown(tree, e);
e.Handled = true;
break;
}
case Keys.Add:
{
e.Handled = PlusKeyDown(tree, e);
break;
}
case Keys.Subtract:
{
e.Handled = MinusKeyDown(tree, e);
break;
}
case Keys.F2:
{
F2KeyDown(tree, e);
break;
}
default:
{
if (e.Control && e.KeyCode == Keys.C)
CopyKeyDown(tree, e);
else if (e.Control && e.KeyCode == Keys.V)
PasteKeyDown(tree, e);
break;
}
}
}
private static bool MinusKeyDown(AdvTree tree, KeyEventArgs e)
{
Node node = tree.SelectedNode;
if (node != null && tree.SelectedNodes.Count == 1 && node.Expanded)
{
node.Collapse();
return true;
}
return false;
}
private static bool PlusKeyDown(AdvTree tree, KeyEventArgs e)
{
Node node = tree.SelectedNode;
if (node != null && tree.SelectedNodes.Count == 1 && !node.Expanded)
{
node.Expand();
return true;
}
return false;
}
private static void PasteKeyDown(AdvTree tree, KeyEventArgs args)
{
if (tree.SelectedNode != null)
tree.SelectedNode.InvokeKeyboardPaste(args);
}
private static void CopyKeyDown(AdvTree tree, KeyEventArgs args)
{
if (tree.SelectedNode != null)
tree.SelectedNode.InvokeKeyboardCopy(args);
}
private static void F2KeyDown(AdvTree tree, KeyEventArgs e)
{
if (tree.EditSelectedCell(eTreeAction.Keyboard))
e.Handled = true;
}
public static void SpaceKeyDown(AdvTree tree, KeyEventArgs e)
{
Node node = tree.SelectedNode;
if (node != null && node.CheckBoxVisible && node.Enabled)
{
if (node.CheckBoxThreeState)
{
if (node.CheckState == CheckState.Checked)
node.SetChecked(CheckState.Indeterminate, eTreeAction.Keyboard);
else if (node.CheckState == CheckState.Unchecked)
node.SetChecked(CheckState.Checked, eTreeAction.Keyboard);
else if (node.CheckState == CheckState.Indeterminate)
node.SetChecked(CheckState.Unchecked, eTreeAction.Keyboard);
}
else
node.SetChecked(!node.Checked, eTreeAction.Keyboard);
e.Handled = true;
}
}
public static void EnterKeyDown(AdvTree tree, KeyEventArgs e)
{
if (tree.SelectedNode != null && tree.SelectedNode.Nodes.Count > 0)
{
tree.SelectedNode.Toggle(eTreeAction.Keyboard);
}
}
public static bool NavigateKeyDown(AdvTree tree, KeyEventArgs e)
{
if(tree.SelectedNode==null)
{
if(tree.DisplayRootNode!=null)
tree.SelectNode(tree.DisplayRootNode, eTreeAction.Keyboard);
else if (tree.Nodes.Count > 0)
{
Node firstSelectable = NodeOperations.GetFirstVisibleNode(tree);
if (firstSelectable != null)
{
while (firstSelectable!=null && !firstSelectable.Selectable)
firstSelectable = NodeOperations.GetNextVisibleNode(firstSelectable);
if (firstSelectable != null)
tree.SelectNode(firstSelectable, eTreeAction.Keyboard);
}
}
return true;
}
Node node = tree.SelectedNode;
if (node != null && !node.IsKeyboardNavigationEnabled(e))
{
return false;
}
if(e.KeyCode == Keys.Right)
{
if (node != null && node.Cells.Count > 1 && tree.SelectionPerCell && node.CellNavigationEnabled)
{
if (node.SelectedCell == null)
node.SetSelectedCell(NodeOperations.GetNextVisibleCell(node, -1), eTreeAction.Keyboard);
else
node.SetSelectedCell(NodeOperations.GetNextVisibleCell(node, node.Cells.IndexOf(node.SelectedCell)), eTreeAction.Keyboard);
return true;
}
if (tree.View == eView.Tile)
{
Node nextNode = NodeOperations.GetNextVisibleNode(node);
if (nextNode != null)
{
if (node.Expanded || !node.HasChildNodes)
tree.SelectNode(nextNode, eTreeAction.Keyboard);
else
node.Expand(eTreeAction.Keyboard);
}
else if (node != null && node.ExpandVisibility == eNodeExpandVisibility.Visible && !node.Expanded)
node.Expand(eTreeAction.Keyboard);
}
else
{
Node childNode = NodeOperations.GetFirstVisibleChildNode(node);
if (childNode != null)
{
if (node.Expanded)
tree.SelectNode(childNode, eTreeAction.Keyboard);
else
node.Expand(eTreeAction.Keyboard);
}
else if (node != null && node.ExpandVisibility == eNodeExpandVisibility.Visible && !node.Expanded)
node.Expand(eTreeAction.Keyboard);
}
}
else if(e.KeyCode == Keys.Left)
{
if (node != null && node.Cells.Count > 1 && tree.SelectionPerCell && node.CellNavigationEnabled)
{
if (node.SelectedCell == null)
node.SetSelectedCell(NodeOperations.GetPreviousVisibleCell(node, node.Cells.Count - 1), eTreeAction.Keyboard);
else
node.SetSelectedCell(NodeOperations.GetPreviousVisibleCell(node, node.Cells.IndexOf(node.SelectedCell)), eTreeAction.Keyboard);
return true;
}
if (tree.View == eView.Tile)
{
Node previousNode = NodeOperations.GetPreviousVisibleNode(node);
if (previousNode != null)
tree.SelectNode(previousNode, eTreeAction.Keyboard);
}
else
{
if (node.Expanded && node.IsSelected && NodeOperations.GetFirstVisibleChildNode(node) != null)
node.Collapse(eTreeAction.Keyboard);
else if (node.Parent != null)
tree.SelectNode(node.Parent, eTreeAction.Keyboard);
}
}
else if (e.KeyCode == Keys.End)
{
Node last = NodeOperations.GetLastVisibleNode(tree);
if (last != null)
{
if (!last.Selectable)
{
while (last != null)
{
last = NodeOperations.GetPreviousVisibleNode(last);
if (last!=null && last.Selectable) break;
}
}
if (last != null)
tree.SelectNode(last, eTreeAction.Keyboard);
}
}
else if (e.KeyCode == Keys.Home || e.KeyCode == Keys.PageDown && node == null)
{
Node first = NodeOperations.GetFirstVisibleNode(tree);
if (first != null)
{
if (!first.Selectable)
{
while (first != null)
{
first = NodeOperations.GetNextVisibleNode(first);
if (first != null && first.Selectable) break;
}
}
if (first != null)
tree.SelectNode(first, eTreeAction.Keyboard);
}
}
else if (e.KeyCode == Keys.PageDown)
{
// Find last fully rendered node
Node lastNode = NodeOperations.GetLastDisplayedNode(tree);
if (lastNode != null)
{
if (tree.SelectedNode == lastNode)
{
if (tree.VScrollBar != null && tree.AutoScroll)
{
tree.AutoScrollPosition = new Point(tree.AutoScrollPosition.X, Math.Max(tree.AutoScrollPosition.Y - tree.VScrollBar.LargeChange, -(tree.VScrollBar.Maximum - tree.VScrollBar.LargeChange)));
lastNode = NodeOperations.GetLastDisplayedNode(tree);
}
}
}
if (lastNode != null)
tree.SelectNode(lastNode, eTreeAction.Keyboard);
}
else if (e.KeyCode == Keys.PageUp)
{
// Find last fully rendered node
Node firstNode = NodeOperations.GetFirstDisplayedNode(tree);
if (firstNode != null)
{
if (tree.SelectedNode == firstNode)
{
if (tree.VScrollBar != null && tree.AutoScroll && tree.AutoScrollPosition.Y < 0)
{
tree.AutoScrollPosition = new Point(tree.AutoScrollPosition.X, Math.Min(0, tree.AutoScrollPosition.Y + tree.VScrollBar.LargeChange));
firstNode = NodeOperations.GetFirstDisplayedNode(tree);
}
}
}
if (firstNode != null)
tree.SelectNode(firstNode, eTreeAction.Keyboard);
}
else if ((e.KeyCode & Keys.Down) == Keys.Down)
{
int currentCell = 0;
if (node != null && node.SelectedCell != null) currentCell = node.Cells.IndexOf(node.SelectedCell);
Node nextNode = NodeOperations.GetNextVisibleNode(node);
// Adjust nextNode so the multi-selection is proper
if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 1)
{
if (tree.SelectedNodes[0].Bounds.Y > tree.SelectedNodes[tree.SelectedNodes.Count - 1].Bounds.Y)
nextNode = tree.SelectedNodes[tree.SelectedNodes.Count - 1];
}
if (nextNode != null)
{
if (!nextNode.CanSelect)
{
int counter = 0;
while (nextNode != null && counter < 100)
{
nextNode = NodeOperations.GetNextVisibleNode(nextNode);
if (nextNode != null && nextNode.CanSelect) break;
}
}
if (nextNode != null)
{
if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 0)
{
if (tree.MultiSelectRule == eMultiSelectRule.SameParent && tree.SelectedNodes[0].Parent != nextNode.Parent) return true;
if (nextNode.IsSelected)
tree.SelectedNodes.Remove(nextNode, eTreeAction.Keyboard);
else
tree.SelectedNodes.Add(nextNode, eTreeAction.Keyboard);
nextNode.EnsureVisible();
}
else
{
tree.SelectNode(nextNode, eTreeAction.Keyboard);
if (tree.SelectionPerCell && currentCell < nextNode.Cells.Count && currentCell > 0)
nextNode.SetSelectedCell(nextNode.Cells[currentCell], eTreeAction.Keyboard);
}
}
}
}
else if ((e.KeyCode & Keys.Up) == Keys.Up)
{
int currentCell = 0;
if (node != null && node.SelectedCell != null) currentCell = node.Cells.IndexOf(node.SelectedCell);
Node prevNode = NodeOperations.GetPreviousVisibleNode(node);
if (prevNode != null)
{
if (!prevNode.CanSelect)
{
int counter = 0;
while (prevNode != null && counter < 100)
{
prevNode = NodeOperations.GetPreviousVisibleNode(prevNode);
if (prevNode != null && prevNode.CanSelect) break;
}
}
if (prevNode != null)
{
if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 0)
{
if (tree.MultiSelectRule == eMultiSelectRule.SameParent && tree.SelectedNodes[0].Parent != prevNode.Parent) return true;
if (prevNode.IsSelected)
{
tree.SelectedNodes.Remove(tree.SelectedNodes[tree.SelectedNodes.Count - 1], eTreeAction.Keyboard);
}
else
tree.SelectedNodes.Add(prevNode, eTreeAction.Keyboard);
prevNode.EnsureVisible();
}
else if (prevNode != null)
{
tree.SelectNode(prevNode, eTreeAction.Keyboard);
if (tree.SelectionPerCell && currentCell < prevNode.Cells.Count && currentCell > 0)
prevNode.SetSelectedCell(prevNode.Cells[currentCell], eTreeAction.Keyboard);
}
}
}
}
return true;
}
}
}

View File

@ -0,0 +1,393 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Layout
{
internal class CellTileLayout : CellLayout
{
/// <summary>
/// Initializes a new instance of the CellTileLayout class.
/// </summary>
public CellTileLayout(LayoutSettings layoutSettings) : base(layoutSettings)
{
}
public override Size LayoutCells(NodeLayoutContextInfo layoutInfo, int x, int y)
{
eCellLayout layout = layoutInfo.CellLayout;
if (layoutInfo.ContextNode.CellLayout != layoutInfo.CellLayout && layoutInfo.ContextNode.CellLayout != eCellLayout.Default)
layout = layoutInfo.ContextNode.CellLayout;
if (layout == eCellLayout.Default && !(layoutInfo.ContextNode.HasChildNodes && layoutInfo.IsViewGroupping) && layoutInfo.ContextNode.ImageAlignment == eCellPartAlignment.Default)
{
return TileLayout(layoutInfo, x, y);
}
else
return base.LayoutCells(layoutInfo, x, y);
}
private Size TileLayout(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node = layoutInfo.ContextNode;
int height = 0, width = 0, realHeight = 0;
//eHorizontalAlign align = eHorizontalAlign.Left;
Size tileSize = layoutInfo.TileSize;
int iVisibleCells = 0;
int cellCount = node.Cells.Count;
bool isVerticalOverflow = false;
for (int i = 0; i < cellCount; i++)
{
Cell cell = node.Cells[i];
bool bCellVisible = isVerticalOverflow ? false : true;
// Setup cell layout helper class
LayoutCellInfo cellLayout = this.GetLayoutCellInfo();
cellLayout.Top = y;
cellLayout.Left = x;
cellLayout.CellWidth = tileSize.Width;
cellLayout.ContextCell = cell;
cellLayout.Graphics = layoutInfo.Graphics;
cellLayout.LeftToRight = layoutInfo.LeftToRight;
cellLayout.Font = layoutInfo.DefaultFont;
cellLayout.View = layoutInfo.View;
cellLayout.CellIndex = i;
if (cell.Layout != eCellPartLayout.Default)
cellLayout.VerticalPartAlignment = (cell.Layout == eCellPartLayout.Vertical);
else if (layoutInfo.CellPartLayout != eCellPartLayout.Default)
cellLayout.VerticalPartAlignment = (layoutInfo.CellPartLayout == eCellPartLayout.Vertical);
// Prepare union style
if (cell.StyleNormal != null)
cellLayout.LayoutStyle = cell.StyleNormal;
else
cellLayout.LayoutStyle = layoutInfo.DefaultCellStyle;
this.LayoutSingleTileCell(cellLayout);
if (bCellVisible && y + cell.BoundsRelative.Height > tileSize.Height && i > 0)
{
isVerticalOverflow = true;
bCellVisible = false;
}
cell.SetVisible(bCellVisible);
if (bCellVisible)
{
iVisibleCells++;
y += cell.BoundsRelative.Height;
height += cell.BoundsRelative.Height;
if (cell.BoundsRelative.Height > 0)
{
y += this.CellVerticalSpacing;
height += this.CellVerticalSpacing;
}
if (cell.BoundsRelative.Width > width)
width = cell.BoundsRelative.Width;
if (i == 0)
{
realHeight += cell.BoundsRelative.Height;
if (cell.BoundsRelative.Height > 0)
realHeight += this.CellVerticalSpacing;
}
else
realHeight = Math.Max(realHeight, height);
// Align other cells under the text of the first cell and to the right of the image, if any
if (i == 0 && !cell.Images.LargestImageSize.IsEmpty && cellCount > 1)
{
Size largestImageSize = Dpi.ImageSize(cell.Images.LargestImageSize);
if (cell.TextContentBounds.IsEmpty)
x += largestImageSize.Width + this.ImageTextSpacing;
else
x += (cell.TextContentBounds.X - x);
tileSize.Width = cell.TextContentBounds.Width;
height -= cell.BoundsRelative.Height;
height += cell.TextContentBounds.Height;
y -= cell.BoundsRelative.Height;
y += cell.TextContentBounds.Height;
}
}
}
// Take last added spacing off
y -= this.CellVerticalSpacing;
height -= this.CellVerticalSpacing;
realHeight -= this.CellVerticalSpacing;
if (node.Cells[0].BoundsRelative.Height > height && !node.Cells[0].Images.LargestImageSize.IsEmpty)
{
int textOffset = ((realHeight - height) / iVisibleCells) / 2;
if (textOffset > 0)
{
foreach (Cell cell in node.Cells)
{
if (!cell.IsVisible) continue;
cell.TextContentBounds = new Rectangle(cell.TextContentBounds.X, cell.TextContentBounds.Y + textOffset, cell.TextContentBounds.Width, cell.TextContentBounds.Height);
}
}
}
else if(iVisibleCells == 1)
{
Rectangle rtc = node.Cells[0].TextContentBounds;
node.Cells[0].TextContentBounds = new Rectangle(rtc.X, rtc.Y, rtc.Width, node.Cells[0].BoundsRelative.Height);
}
// Additional pass needed if horizontal alignment is other than left and there is more than one cell visible
//if (align != eHorizontalAlign.Left && iVisibleCells > 1)
//{
// foreach (Cell cell in node.Cells)
// {
// if (!cell.IsVisible)
// continue;
// if (align == eHorizontalAlign.Center)
// this.Offset(cell, (width - cell.BoundsRelative.Width) / 2, 0);
// else // Right aligned cells
// this.Offset(cell, width - cell.BoundsRelative.Width, 0);
// }
//}
if (width < layoutInfo.TileSize.Width)
width = layoutInfo.TileSize.Width;
if (realHeight < layoutInfo.TileSize.Height)
realHeight = layoutInfo.TileSize.Height;
return new Size(width, realHeight);
}
protected virtual void LayoutSingleTileCell(LayoutCellInfo info)
{
Size textSize = Size.Empty;
Font font = info.Font;
int fontHeight = info.FontHeight;
int height = 0;
if (info.LayoutStyle.Font != null)
{
font = info.LayoutStyle.Font;
fontHeight = font.Height;
}
info.ContextCell.OnLayoutCell();
Size largestImageSize = info.ContextCell.Images.LargestImageSize;
if (largestImageSize.IsEmpty && HasImage(info.ContextCell))
info.ContextCell.Images.RefreshLargestImageSize();
largestImageSize = Dpi.ImageSize(info.ContextCell.Images.LargestImageSize);
if (info.ContextCell.HostedControl != null)
{
Size controlSize = info.ContextCell.HostedControl.Size;
if (!info.ContextCell.HostedControlSize.IsEmpty)
controlSize = info.ContextCell.HostedControlSize;
if (info.CellWidth == 0)
textSize = new Size(controlSize.Width, controlSize.Height);
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize = new Size(availTextWidth, controlSize.Height);
}
}
else if (info.ContextCell.HostedItem != null)
{
if (info.CellWidth != 0) info.ContextCell.HostedItem.WidthInternal = info.CellWidth;
info.ContextCell.HostedItem.RecalcSize();
Size controlSize = info.ContextCell.HostedItem.Size;
if (info.CellWidth == 0)
textSize = new Size(controlSize.Width, controlSize.Height);
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize = new Size(availTextWidth, controlSize.Height);
info.ContextCell.HostedItem.WidthInternal = availTextWidth;
}
}
else
{
// Calculate Text Width and Height
if (info.CellWidth == 0)
{
if (info.ContextCell.TextMarkupBody == null)
{
string text = info.ContextCell.DisplayText;
if (text != "")
{
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.LayoutStyle.MaximumWidth);
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.ContextCell.Parent.Style.MaximumWidth);
else
textSize = TextDrawing.MeasureString(info.Graphics, text, font, 0, eTextFormat.Left | eTextFormat.LeftAndRightPadding | eTextFormat.GlyphOverhangPadding | eTextFormat.NoPrefix);
#if (FRAMEWORK20)
if (!BarFunctions.IsVista && BarUtilities.UseTextRenderer) textSize.Width += 4;
#endif
}
else if (largestImageSize.IsEmpty && !info.ContextCell.CheckBoxVisible)
{
textSize = new Size(5, fontHeight);
}
}
else
{
Size availSize = new Size(1600, 1);
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
availSize.Width = info.LayoutStyle.MaximumWidth;
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
availSize.Width = info.ContextCell.Parent.Style.MaximumWidth;
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
availTextWidth -= largestImageSize.Width +
(largestImageSize.Width > 0 ? ImageTextSpacing * 2 : 0);
if (info.ContextCell.CheckBoxVisible)
availTextWidth -= CheckBoxSize.Width + ImageTextSpacing * 2;
int cellHeight = fontHeight;
if (info.LayoutStyle.WordWrap || info.ContextCell.TextMarkupBody != null)
{
cellHeight = info.LayoutStyle.MaximumHeight - info.LayoutStyle.MarginTop -
info.LayoutStyle.MarginBottom - info.LayoutStyle.PaddingTop - info.LayoutStyle.PaddingBottom;
if (info.ContextCell.TextMarkupBody == null)
{
if (availTextWidth > 0)
{
if (cellHeight > 0)
textSize = TextDrawing.MeasureString(info.Graphics, info.ContextCell.DisplayText, font, new Size(availTextWidth, cellHeight), info.LayoutStyle.TextFormat);
else
textSize = TextDrawing.MeasureString(info.Graphics, info.ContextCell.DisplayText, font, availTextWidth, info.LayoutStyle.TextFormat);
}
}
else
{
Size availSize = new Size(availTextWidth, 1);
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
availSize.Width = availTextWidth;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
textSize = new Size(availTextWidth, cellHeight);
}
}
if (info.LayoutStyle.WordWrap)
info.ContextCell.WordWrap = true;
else
info.ContextCell.WordWrap = false;
height = (int)Math.Max(height, Math.Ceiling((double)textSize.Height));
if (info.VerticalPartAlignment)
{
if (largestImageSize.Height > 0)
height += largestImageSize.Height + this.ImageTextSpacing;
if (info.ContextCell.CheckBoxVisible)
height += CheckBoxSize.Height + this.ImageCheckBoxSpacing;
}
else
{
if (largestImageSize.Height > height)
height = largestImageSize.Height;
if (info.ContextCell.CheckBoxVisible && CheckBoxSize.Height > height)
height = CheckBoxSize.Height;
}
Rectangle r = new Rectangle(info.Left + ElementStyleLayout.LeftWhiteSpace(info.LayoutStyle),
info.Top + ElementStyleLayout.TopWhiteSpace(info.LayoutStyle)
, info.CellWidth, height);
if (r.Width == 0)
{
if (info.VerticalPartAlignment)
{
r.Width = (int)Math.Ceiling((double)textSize.Width);
if (largestImageSize.Width > r.Width)
r.Width = (largestImageSize.Width + this.ImageTextSpacing);
if (info.ContextCell.CheckBoxVisible && CheckBoxSize.Width > r.Width)
r.Width += (CheckBoxSize.Width + this.ImageTextSpacing);
}
else
{
r.Width = (int)Math.Ceiling((double)textSize.Width);
if (largestImageSize.Width > 0)
r.Width += (largestImageSize.Width + this.ImageTextSpacing);
if (info.ContextCell.CheckBoxVisible)
r.Width += (CheckBoxSize.Width + this.ImageTextSpacing);
}
}
// Now that we have cell bounds store them
Rectangle rCellBounds = new Rectangle(info.Left, info.Top, info.CellWidth, r.Height + info.LayoutStyle.MarginTop + info.LayoutStyle.MarginBottom + info.LayoutStyle.PaddingTop + info.LayoutStyle.PaddingBottom);
if (rCellBounds.Width == 0)
rCellBounds.Width = r.Width + ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
info.ContextCell.SetBounds(rCellBounds);
// Set position of the check box
if (info.ContextCell.CheckBoxVisible && rCellBounds.Width >= this.CheckBoxSize.Width)
{
eVerticalAlign va = GetCheckBoxVerticalAlign(info.ContextCell.CheckBoxAlignment, info.View);
eHorizontalAlign ha = GetCheckBoxHorizontalAlign(info.ContextCell.CheckBoxAlignment, info.LeftToRight, info.View);
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || !largestImageSize.IsEmpty))
ha = eHorizontalAlign.Left;
if (info.VerticalPartAlignment)
info.ContextCell.SetCheckBoxBounds(AlignContentVertical(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetCheckBoxBounds(AlignContent(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetCheckBoxBounds(Rectangle.Empty);
// Set Position of the image
if (!largestImageSize.IsEmpty && rCellBounds.Width >= largestImageSize.Width)
{
eVerticalAlign va = GetVerticalAlign(info.ContextCell.ImageAlignment, info.View);
eHorizontalAlign ha = GetHorizontalAlign(info.ContextCell.ImageAlignment, info.LeftToRight, info.View);
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || info.ContextCell.CheckBoxVisible))
ha = eHorizontalAlign.Left;
if (info.VerticalPartAlignment)
info.ContextCell.SetImageBounds(AlignContentVertical(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetImageBounds(AlignContent(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetImageBounds(Rectangle.Empty);
// Set position of the text
//info.ContextCell.SetTextBounds(Rectangle.Empty);
if (!textSize.IsEmpty)
{
if (info.CellWidth > 0)
r.Width -= 2;
if (info.View == eView.Tile && info.CellIndex == 0)
info.ContextCell.TextContentBounds = new Rectangle(r.X, r.Y, textSize.Width, textSize.Height + 1);
else
info.ContextCell.TextContentBounds = r;
}
else
info.ContextCell.TextContentBounds = Rectangle.Empty;
}
}
}

View File

@ -0,0 +1,193 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Layout
{
/// <summary>
/// Class that is used to layout column header.
/// </summary>
internal class ColumnHeaderLayout
{
public ColumnHeaderLayout()
{
}
// Assumes that layoutInfo is up-to-date and that Node that is connected with
// columns is already processed and it's size and location calculated.
// layoutInfo.Top member reflects the next position below the node
// layoutInfo.LevelOffset should reflect the X offset for the child nodes.
public static int LayoutColumnHeader(NodeLayoutContextInfo layoutInfo,int x, int y, int clientWidth, int cellHorizontalSpacing)
{
ColumnHeaderCollection columns = null;
Node node=layoutInfo.ContextNode;
if (node == null)
columns = layoutInfo.TreeColumns;
else
columns = node.NodesColumns;
columns.UsesRelativeSize = false;
int height=0;
bool adjustHeight = false;
Rectangle totalBounds = Rectangle.Empty;
ColumnHeader lastVisibleColumn = null;
ColumnHeader stretchToFillColumn = null;
bool allRelative = true;
bool firstVisible = true;
for (int i = 0; i < columns.Count; i++)
{
ColumnHeader col = columns.ColumnAtDisplayIndex(i);
col.IsLastVisible = false;
if(!col.Visible)
continue;
col.IsFirstVisible = firstVisible;
firstVisible = false;
//if(col.SizeChanged)
{
// Column for child nodes is always placed below the current node and
// is not included in the node's rectangle
Rectangle bounds=Rectangle.Empty;
bounds.X=x;
bounds.Y=y;
if (col.Width.AutoSize)
{
int autoWidth = col.Width.AutoSizeWidth;
if (col.Width.AutoSizeMinHeader)
{
Font headerFont = layoutInfo.DefaultFont;
if (!string.IsNullOrEmpty(col.StyleNormal))
{
ElementStyle style = layoutInfo.Styles[col.StyleNormal];
if (style != null && style.Font != null)
headerFont = style.Font;
}
else if (layoutInfo.ColumnStyle != null && layoutInfo.ColumnStyle.Font != null)
headerFont = layoutInfo.ColumnStyle.Font;
if (headerFont != null)
{
int columnHeaderTextWidth = (int)Math.Ceiling(layoutInfo.Graphics.MeasureString(col.Text, headerFont).Width) + 2;
autoWidth = Math.Max(autoWidth, columnHeaderTextWidth);
col.Width.SetAutoSizeWidth(autoWidth);
}
}
bounds.Width = autoWidth;
allRelative = false;
}
else if (col.Width.Absolute > 0)
{
bounds.Width = col.Width.Absolute;
allRelative = false;
}
else if (col.Width.Absolute == -1)
{
bounds.Width = 0;
allRelative = false;
}
else if (col.Width.Relative > 0)
{
if (col.IsFirstVisible)
{
clientWidth -= layoutInfo.ExpandPartWidth;
bounds.Width = (clientWidth * col.Width.Relative) / 100 - cellHorizontalSpacing;
bounds.Width += layoutInfo.ExpandPartWidth;
}
else
bounds.Width = (clientWidth * col.Width.Relative) / 100 - cellHorizontalSpacing;
columns.UsesRelativeSize = true;
}
lastVisibleColumn = col;
if (col.StretchToFill)
{
stretchToFillColumn = col;
columns.UsesRelativeSize = true;
}
if(col.StyleNormal=="" && col.StyleMouseDown=="" && col.StyleMouseOver=="")
{
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
}
else
{
Size sz=Size.Empty;
if(col.StyleNormal!="")
{
ElementStyleLayout.CalculateStyleSize(layoutInfo.Styles[col.StyleNormal],layoutInfo.DefaultFont);
sz=layoutInfo.Styles[col.StyleNormal].Size;
}
if(sz.Height==0)
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
else
bounds.Height=sz.Height;
}
if (col.Image != null && col.Image.Height+4>bounds.Height)
{
bounds.Height = col.Image.Height + 4;
}
col.SetBounds(bounds);
col.SizeChanged=false;
x += (bounds.Width + cellHorizontalSpacing);
if (bounds.Height > height)
{
if (height > 0)
adjustHeight = true;
height = bounds.Height;
}
else if (bounds.Height < height)
adjustHeight = true;
}
if (totalBounds.IsEmpty)
totalBounds = col.Bounds;
else
totalBounds = Rectangle.Union(totalBounds, col.Bounds);
}
if (adjustHeight)
{
foreach (ColumnHeader col in columns)
{
col.SetBounds(new Rectangle(col.Bounds.X, col.Bounds.Y, col.Bounds.Width, height));
}
}
if (lastVisibleColumn != null && allRelative)
{
lastVisibleColumn.SetBounds(new Rectangle(lastVisibleColumn.Bounds.X, lastVisibleColumn.Bounds.Y, lastVisibleColumn.Bounds.Width + cellHorizontalSpacing, lastVisibleColumn.Bounds.Height));
totalBounds = Rectangle.Union(totalBounds, lastVisibleColumn.Bounds);
}
if (lastVisibleColumn != null) lastVisibleColumn.IsLastVisible = true;
if (stretchToFillColumn != null && totalBounds.Width < clientWidth)
{
int stretch = clientWidth - totalBounds.Width;
if (stretchToFillColumn.IsFirstVisible && stretchToFillColumn.IsLastVisible) // Single column visible only case
stretch -= layoutInfo.Indent;
else if (stretchToFillColumn.Parent != null && stretchToFillColumn.Parent.ParentNode != null)
stretch -= layoutInfo.Indent;
stretchToFillColumn.SetBounds(new Rectangle(stretchToFillColumn.Bounds.X, stretchToFillColumn.Bounds.Y,
stretchToFillColumn.Bounds.Width + stretch, stretchToFillColumn.Bounds.Height));
totalBounds = Rectangle.Union(totalBounds, stretchToFillColumn.Bounds);
if (!stretchToFillColumn.IsLastVisible) // Offset columns to the right if this was not last visible column
{
int startIndex = columns.GetDisplayIndex(stretchToFillColumn) + 1;
for (int i = startIndex; i < columns.Count; i++)
{
ColumnHeader col = columns.ColumnAtDisplayIndex(i);
if (!col.Visible) continue;
col.SetBounds(new Rectangle(col.Bounds.X + stretch, col.Bounds.Y, col.Bounds.Width, col.Bounds.Height));
totalBounds = Rectangle.Union(totalBounds, col.Bounds);
}
}
}
columns.SetBounds(totalBounds);
return height;
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace DevComponents.AdvTree.Layout
{
internal class LayoutSettings
{
#region Internal Implementation
private int _NodeVerticalSpacing = 3;
/// <summary>
/// Gets or sets the vertical spacing between nodes in pixels.
/// </summary>
public virtual int NodeVerticalSpacing
{
get { return _NodeVerticalSpacing; }
set { _NodeVerticalSpacing = value; }
}
private int _NodeHorizontalSpacing = 4;
/// <summary>
/// Gets or sets the horizontal spacing between nodes in pixels.
/// </summary>
public virtual int NodeHorizontalSpacing
{
get { return _NodeHorizontalSpacing; }
set { _NodeHorizontalSpacing = value; }
}
private int _CellHorizontalSpacing = 5;
/// <summary>
/// Returns horizontal spacing between cells in a node
/// </summary>
public int CellHorizontalSpacing
{
get { return _CellHorizontalSpacing; }
set
{
_CellHorizontalSpacing = value;
}
}
private int _ExpandAreaWidth = 24;
/// <summary>
/// Returns width of the expand button area. Default is 24 pixels.
/// </summary>
public virtual int ExpandAreaWidth
{
get { return _ExpandAreaWidth; }
set
{
_ExpandAreaWidth = value;
}
}
protected Size _ExpandPartSize = new Size(8, 8);
/// <summary>
/// Gets or sets the size of the expand part that is expanding/collapsing the node. Default value is 8,8.
/// </summary>
public System.Drawing.Size ExpandPartSize
{
get { return _ExpandPartSize; }
set { _ExpandPartSize = value; }
}
private int _CommandAreaWidth = 10;
/// <summary>
/// Gets or sets width of command button area. Default is 8 pixels.
/// </summary>
public virtual int CommandAreaWidth
{
get { return _CommandAreaWidth; }
set { _CommandAreaWidth = value; }
}
#endregion
}
}

View File

@ -0,0 +1,888 @@
using System;
using System.Drawing;
using DevComponents.DotNetBar;
using System.Collections;
namespace DevComponents.AdvTree
{
namespace Layout
{
/// <summary>
/// Represents class for Node's cell layout.
/// </summary>
internal class CellLayout
{
public CellLayout(LayoutSettings layoutSettings)
{
_LayoutSettings = layoutSettings;
}
private LayoutSettings _LayoutSettings;
public LayoutSettings LayoutSettings
{
get { return _LayoutSettings; }
set { _LayoutSettings = value; }
}
/// <summary>
/// Offset cell bounds, check box bounds, image bounds and text bounds by specified offset.
/// </summary>
/// <param name="cell">Cell to offset.</param>
/// <param name="x">Horizontal offset in pixels.</param>
/// <param name="y">Vertical offset in pixels.</param>
protected void Offset(Cell cell, int x, int y)
{
if (x == 0 && y == 0) return;
cell.SetBounds(new Rectangle(cell.BoundsRelative.X+x,cell.BoundsRelative.Y+y,cell.BoundsRelative.Width,cell.BoundsRelative.Height));
if(!cell.CheckBoxBoundsRelative.IsEmpty)
cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X+x,cell.CheckBoxBoundsRelative.Y+y,cell.CheckBoxBoundsRelative.Width,cell.CheckBoxBoundsRelative.Height));
if(!cell.ImageBoundsRelative.IsEmpty)
cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X+x,cell.ImageBoundsRelative.Y+y,cell.ImageBoundsRelative.Width,cell.ImageBoundsRelative.Height));
if(!cell.TextContentBounds.IsEmpty)
cell.TextContentBounds=new Rectangle(cell.TextContentBounds.X+x,cell.TextContentBounds.Y+y,cell.TextContentBounds.Width,cell.TextContentBounds.Height);
}
protected virtual void LayoutSingleCell(LayoutCellInfo info)
{
Size textSize = Size.Empty;
Font font = info.Font;
int fontHeight = info.FontHeight; // Uses cached FontHeight reference. Huge performance savings on some fonts!!!
int height = 0;
if (info.LayoutStyle.Font != null)
{
font = info.LayoutStyle.Font;
fontHeight = font.Height;
}
info.ContextCell.OnLayoutCell();
if (info.ContextCell.Images.LargestImageSize.IsEmpty && HasImage(info.ContextCell))
info.ContextCell.Images.RefreshLargestImageSize();
Size largestImageSize = Dpi.ImageSize(info.ContextCell.Images.LargestImageSize);
Size checkBoxSize = Dpi.Size(CheckBoxSize);
if (info.ContextCell.HostedControl != null)
{
Size controlSize = info.ContextCell.HostedControl.Size;
if (!info.ContextCell.HostedControlSize.IsEmpty)
controlSize = info.ContextCell.HostedControlSize;
if (info.CellWidth == 0)
textSize = new Size(controlSize.Width, controlSize.Height);
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize = new Size(availTextWidth, controlSize.Height);
}
}
else if (info.ContextCell.HostedItem != null)
{
if (info.CellWidth != 0) info.ContextCell.HostedItem.WidthInternal = info.CellWidth;
info.ContextCell.HostedItem.RecalcSize();
Size controlSize = info.ContextCell.HostedItem.Size;
if (info.CellWidth == 0)
textSize = new Size(controlSize.Width, controlSize.Height);
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize = new Size(availTextWidth, controlSize.Height);
info.ContextCell.HostedItem.WidthInternal = availTextWidth;
}
}
else
{
// Calculate Text Width and Height
string cellDisplayText = info.ContextCell.DisplayText;
if (info.CellWidth == 0)
{
if (info.ContextCell.TextMarkupBody == null)
{
string text = cellDisplayText;
if (text != "")
{
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.LayoutStyle.MaximumWidth);
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
textSize = TextDrawing.MeasureString(info.Graphics, text, font, info.ContextCell.Parent.Style.MaximumWidth);
else
textSize = TextDrawing.MeasureString(info.Graphics, text, font, 0, eTextFormat.Left | eTextFormat.LeftAndRightPadding | eTextFormat.GlyphOverhangPadding | eTextFormat.NoPrefix);
#if (FRAMEWORK20)
if (!BarFunctions.IsVista && BarUtilities.UseTextRenderer) textSize.Width += 4;
#endif
}
else if (largestImageSize.IsEmpty && !info.ContextCell.CheckBoxVisible)
{
textSize = new Size(5, fontHeight);
}
}
else
{
Size availSize = new Size(1600, 1);
if (info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth > 0)
availSize.Width = info.LayoutStyle.MaximumWidth;
else if (info.ContextCell.Parent != null && info.ContextCell.Parent.Style != null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth > 0)
availSize.Width = info.ContextCell.Parent.Style.MaximumWidth;
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
{
int availTextWidth = info.CellWidth -
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
availTextWidth -= largestImageSize.Width +
(largestImageSize.Width > 0 ? ImageTextSpacing * 2 : 0);
if (info.ContextCell.CheckBoxVisible)
availTextWidth -= checkBoxSize.Width + ImageTextSpacing * 2;
int cellHeight = fontHeight;
if (info.LayoutStyle.WordWrap || info.ContextCell.TextMarkupBody != null)
{
cellHeight = info.LayoutStyle.MaximumHeight - info.LayoutStyle.MarginTop -
info.LayoutStyle.MarginBottom - info.LayoutStyle.PaddingTop - info.LayoutStyle.PaddingBottom;
if (info.ContextCell.TextMarkupBody == null)
{
if (availTextWidth > 0)
{
if (cellHeight > 0)
{
textSize = TextDrawing.MeasureString(info.Graphics, cellDisplayText, font, new Size(availTextWidth, cellHeight), info.LayoutStyle.TextFormat);
if (textSize.Height == 0) textSize.Height = cellHeight;
}
else if (!string.IsNullOrEmpty(cellDisplayText))
textSize = TextDrawing.MeasureString(info.Graphics, cellDisplayText, font, availTextWidth, info.LayoutStyle.TextFormat);
else
textSize = new Size(availTextWidth, fontHeight);
}
}
else
{
Size availSize = new Size(availTextWidth, 1);
DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
availSize.Width = availTextWidth;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
textSize = new Size(availTextWidth, cellHeight);
}
}
if (info.LayoutStyle.WordWrap)
info.ContextCell.WordWrap = true;
else
info.ContextCell.WordWrap = false;
height = (int)Math.Max(height, Math.Ceiling((double)textSize.Height));
if (info.VerticalPartAlignment)
{
if (largestImageSize.Height > 0)
height += largestImageSize.Height + this.ImageTextSpacing;
if (info.ContextCell.CheckBoxVisible)
height += checkBoxSize.Height + this.ImageCheckBoxSpacing;
}
else
{
if (largestImageSize.Height > height)
height = largestImageSize.Height;
if (info.ContextCell.CheckBoxVisible && checkBoxSize.Height > height)
height = checkBoxSize.Height;
}
Rectangle r = new Rectangle(info.Left + ElementStyleLayout.LeftWhiteSpace(info.LayoutStyle),
info.Top + ElementStyleLayout.TopWhiteSpace(info.LayoutStyle)
, info.CellWidth, height);
if (r.Width == 0)
{
if (info.VerticalPartAlignment)
{
r.Width = (int)Math.Ceiling((double)textSize.Width);
if (largestImageSize.Width > r.Width)
r.Width = (largestImageSize.Width + this.ImageTextSpacing);
if (info.ContextCell.CheckBoxVisible && checkBoxSize.Width > r.Width)
r.Width += (checkBoxSize.Width + this.ImageTextSpacing);
}
else
{
r.Width = (int)Math.Ceiling((double)textSize.Width);
if (largestImageSize.Width > 0)
r.Width += (largestImageSize.Width + this.ImageTextSpacing);
if (info.ContextCell.CheckBoxVisible)
r.Width += (checkBoxSize.Width + this.ImageTextSpacing);
}
}
// Now that we have cell bounds store them
Rectangle rCellBounds = new Rectangle(info.Left, info.Top, info.CellWidth, r.Height + info.LayoutStyle.MarginTop + info.LayoutStyle.MarginBottom + info.LayoutStyle.PaddingTop + info.LayoutStyle.PaddingBottom);
if (rCellBounds.Width == 0)
rCellBounds.Width = r.Width + ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
info.ContextCell.SetBounds(rCellBounds);
// Set position of the check box
//Size checkBoxSize = this.CheckBoxSize;
if (info.ContextCell.CheckBoxVisible && rCellBounds.Width >= checkBoxSize.Width)
{
eVerticalAlign va = GetCheckBoxVerticalAlign(info.ContextCell.CheckBoxAlignment, info.View);
eHorizontalAlign ha = GetCheckBoxHorizontalAlign(info.ContextCell.CheckBoxAlignment, info.LeftToRight, info.View);
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || !largestImageSize.IsEmpty))
ha = eHorizontalAlign.Left;
if (info.VerticalPartAlignment)
info.ContextCell.SetCheckBoxBounds(AlignContentVertical(checkBoxSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetCheckBoxBounds(AlignContent(checkBoxSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetCheckBoxBounds(Rectangle.Empty);
// Set Position of the image
if (!largestImageSize.IsEmpty && rCellBounds.Width >= largestImageSize.Width)
{
eVerticalAlign va = GetVerticalAlign(info.ContextCell.ImageAlignment, info.View);
eHorizontalAlign ha = GetHorizontalAlign(info.ContextCell.ImageAlignment, info.LeftToRight, info.View);
if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || info.ContextCell.CheckBoxVisible) && !info.VerticalPartAlignment)
ha = eHorizontalAlign.Left;
if (info.VerticalPartAlignment)
info.ContextCell.SetImageBounds(AlignContentVertical(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetImageBounds(AlignContent(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetImageBounds(Rectangle.Empty);
// Set position of the text
//info.ContextCell.SetTextBounds(Rectangle.Empty);
if (!textSize.IsEmpty)
{
if (info.CellWidth > 0)
{
r.Width -= 2 + ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
}
info.ContextCell.TextContentBounds = r;
}
else
info.ContextCell.TextContentBounds = Rectangle.Empty;
}
protected Rectangle AlignContent(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
case eHorizontalAlign.Center:
{
contentRect.X = boundingRectangle.X + (boundingRectangle.Width - contentRect.Width) / 2;
break;
}
default:
{
contentRect.X=boundingRectangle.X;
boundingRectangle.X=contentRect.Right+contentSpacing;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
}
switch(vertAlign)
{
case eVerticalAlign.Top:
{
contentRect.Y=boundingRectangle.Y;
break;
}
case eVerticalAlign.Middle:
{
contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
break;
}
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
break;
}
}
return contentRect;
}
protected Rectangle AlignContentVertical(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Left:
{
contentRect.X=boundingRectangle.X;
break;
}
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
break;
}
case eHorizontalAlign.Center:
{
contentRect.X=boundingRectangle.X+(boundingRectangle.Width-contentRect.Width)/2;
break;
}
}
switch(vertAlign)
{
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
//case eVerticalAlign.Top:
default:
{
contentRect.Y=boundingRectangle.Y;
boundingRectangle.Y=contentRect.Bottom+contentSpacing;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
// case eVerticalAlign.Middle:
// {
// contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
// break;
// }
}
return contentRect;
}
public static eHorizontalAlign GetHorizontalAlign(eCellPartAlignment align, bool leftToRight, eView view)
{
if (align == eCellPartAlignment.Default)
{
if (view == eView.Tree)
align = eCellPartAlignment.NearCenter;
else if (view == eView.Tile)
align = eCellPartAlignment.NearCenter;
}
if(((align==eCellPartAlignment.NearBottom || align==eCellPartAlignment.NearCenter ||
align==eCellPartAlignment.NearTop) && leftToRight) ||
((align==eCellPartAlignment.FarBottom || align==eCellPartAlignment.FarCenter ||
align==eCellPartAlignment.FarTop) && !leftToRight))
return eHorizontalAlign.Left;
else if(align==eCellPartAlignment.CenterBottom || align==eCellPartAlignment.CenterTop)
return eHorizontalAlign.Center;
return eHorizontalAlign.Right;
}
public static eVerticalAlign GetVerticalAlign(eCellPartAlignment align, eView view)
{
if (align == eCellPartAlignment.Default)
{
if (view == eView.Tree)
align = eCellPartAlignment.NearCenter;
else if (view == eView.Tile)
align = eCellPartAlignment.NearCenter;
}
eVerticalAlign va=eVerticalAlign.Middle;
switch(align)
{
case eCellPartAlignment.FarBottom:
case eCellPartAlignment.NearBottom:
case eCellPartAlignment.CenterBottom:
va=eVerticalAlign.Bottom;
break;
case eCellPartAlignment.FarTop:
case eCellPartAlignment.NearTop:
case eCellPartAlignment.CenterTop:
va=eVerticalAlign.Top;
break;
}
return va;
}
public static eHorizontalAlign GetCheckBoxHorizontalAlign(eCellPartAlignment align, bool leftToRight, eView view)
{
if (align == eCellPartAlignment.Default)
{
if (view == eView.Tree)
align = eCellPartAlignment.NearCenter;
else if (view == eView.Tile)
align = eCellPartAlignment.NearCenter;
}
if (((align == eCellPartAlignment.NearBottom || align == eCellPartAlignment.NearCenter ||
align == eCellPartAlignment.NearTop) && leftToRight) ||
((align == eCellPartAlignment.FarBottom || align == eCellPartAlignment.FarCenter ||
align == eCellPartAlignment.FarTop) && !leftToRight))
return eHorizontalAlign.Left;
else if (align == eCellPartAlignment.CenterBottom || align == eCellPartAlignment.CenterTop)
return eHorizontalAlign.Center;
return eHorizontalAlign.Right;
}
public static eVerticalAlign GetCheckBoxVerticalAlign(eCellPartAlignment align, eView view)
{
if (align == eCellPartAlignment.Default)
{
if (view == eView.Tree)
align = eCellPartAlignment.NearCenter;
else if (view == eView.Tile)
align = eCellPartAlignment.NearCenter;
}
eVerticalAlign va = eVerticalAlign.Middle;
switch (align)
{
case eCellPartAlignment.FarBottom:
case eCellPartAlignment.NearBottom:
case eCellPartAlignment.CenterBottom:
va = eVerticalAlign.Bottom;
break;
case eCellPartAlignment.FarTop:
case eCellPartAlignment.NearTop:
case eCellPartAlignment.CenterTop:
va = eVerticalAlign.Top;
break;
}
return va;
}
private Size _CheckBoxSize = new Size(12, 12);
internal System.Drawing.Size CheckBoxSize
{
get
{
return _CheckBoxSize;
}
set
{
_CheckBoxSize = value;
}
}
internal void ResetCheckBoxSize()
{
_CheckBoxSize = new Size(12, 12);
}
/// <summary>
/// Returns spacing between check box and image if both are displayed
/// </summary>
protected int ImageCheckBoxSpacing
{
get {return 4;}
}
/// <summary>
/// Returns spacing between image or checkbox and text
/// </summary>
protected int ImageTextSpacing
{
get {return 4;}
}
//private int _CellHorizontalSpacing = 5;
///// <summary>
///// Returns horizontal spacing between cells in a node
///// </summary>
//public int CellHorizontalSpacing
//{
// get {return _CellHorizontalSpacing;}
// set
// {
// _CellHorizontalSpacing = value;
// }
//}
/// <summary>
/// Returns vertical spacing between cells in a node
/// </summary>
public int CellVerticalSpacing
{
get {return 1;}
}
/// <summary>
/// Spacing between different parts of the cell, like image, option button, text and expand button area
/// </summary>
public int CellPartSpacing
{
get {return 1;}
}
public virtual Size LayoutCells(NodeLayoutContextInfo layoutInfo, int x, int y)
{
eCellLayout layout=layoutInfo.CellLayout;
if (layoutInfo.ContextNode.CellLayout != layoutInfo.CellLayout && layoutInfo.ContextNode.CellLayout != eCellLayout.Default)
layout = layoutInfo.ContextNode.CellLayout;
if (layout == eCellLayout.Horizontal || layout == eCellLayout.Default && layoutInfo.View == eView.Tree || layoutInfo.View == eView.Tile && layoutInfo.IsViewGroupping && layoutInfo.ContextNode.HasChildNodes)
return this.LayoutCellsHorizontal(layoutInfo, x, y);
else
return this.LayoutCellsVertical(layoutInfo, x, y);
}
protected virtual Size LayoutCellsHorizontal(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
bool adjustHeight = false;
int cellCount = node.Cells.Count;
bool firstVisible = true;
int runningColumnWidth = 0;
for(int i=0;i<cellCount;i++)
{
Cell cell = null;
if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count == cellCount)
cell = node.Cells[layoutInfo.ChildColumns.ColumnInfo[i].AbsoluteIndex];
else if (layoutInfo.DefaultColumns.ColumnInfo.Count == cellCount)
cell = node.Cells[layoutInfo.DefaultColumns.ColumnInfo[i].AbsoluteIndex];
else
cell = node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.View = layoutInfo.View;
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.CellHeight = 0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(cell.Layout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(cell.Layout==eCellPartLayout.Vertical);
else if(layoutInfo.CellPartLayout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(layoutInfo.CellPartLayout==eCellPartLayout.Vertical);
ColumnInfo ci = null;
if ((layoutInfo.DefaultColumns.ColumnInfo.Count > 0 || layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0) &&
(node.Cells.Count > 1 || node.Cells.Count == layoutInfo.DefaultColumns.ColumnInfo.Count ||
layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count == node.Cells.Count))
{
bool usingTopLevelColumns = false;
if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0 && i < layoutInfo.ChildColumns.ColumnInfo.Count)
ci = layoutInfo.ChildColumns.ColumnInfo[i] as ColumnInfo;
else if (i < layoutInfo.DefaultColumns.ColumnInfo.Count)
{
ci = layoutInfo.DefaultColumns.ColumnInfo[i] as ColumnInfo;
usingTopLevelColumns = true;
}
if (ci != null)
{
bCellVisible = ci.Visible;
if (ci.AutoSize && cell.HostedControl == null)
cellLayout.CellWidth = 0;
else
{
cellLayout.CellWidth = ci.Width;
/*if (firstVisible && usingTopLevelColumns && cellLayout.CellWidth > 0)
{
cellLayout.CellWidth = Math.Max(-1, cellLayout.CellWidth - (layoutInfo.Left + x + this.LayoutSettings.CellHorizontalSpacing));
if (cellLayout.CellWidth == 0) cellLayout.CellWidth = -1; // this ensures that cell content is not visible since 0 indicates to take as much space as needed
}
else*/ if(usingTopLevelColumns && cellLayout.CellWidth>0 && runningColumnWidth<layoutInfo.Left+x)
{
// Removed layoutInfo.Left from calculation in case that PaddingLeft was set to larger value on AdvTree.BackgroundStyle to push content to the right
cellLayout.CellWidth = Math.Max(-1, cellLayout.CellWidth - ((layoutInfo.Left + x - layoutInfo.LeftMargin) - runningColumnWidth));
if (cellLayout.CellWidth == 0) cellLayout.CellWidth = -1; // this ensures that cell content is not visible since 0 indicates to take as much space as needed
}
runningColumnWidth += ci.Width + this.LayoutSettings.CellHorizontalSpacing;
}
}
}
else if (layoutInfo.View == eView.Tile)
{
if (layoutInfo.IsViewGroupping && node.HasChildNodes)
{
cellLayout.CellWidth = layoutInfo.ClientRectangle.Width - layoutInfo.Left - layoutInfo.ExpandPartWidth - 1;
}
else
{
cellLayout.CellWidth = layoutInfo.TileSize.Width;
cellLayout.CellHeight = layoutInfo.TileSize.Height;
}
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
{
if(layoutInfo.ContextNode.Style!=null)
{
ElementStyle styleCopy = layoutInfo.DefaultCellStyle.Copy();
styleCopy.ApplyStyle(layoutInfo.ContextNode.Style);
cellLayout.LayoutStyle = styleCopy;
}
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
}
this.LayoutSingleCell(cellLayout);
cell.SetVisible(bCellVisible);
if(bCellVisible)
{
if (ci != null && ci.AutoSize && cell.HostedControl==null)
{
if (ci.ColumnHeader.Parent.ParentNode == null && firstVisible)
ci.MaxWidth = Math.Max(ci.MaxWidth, cell.BoundsRelative.Width + (layoutInfo.Left + x) + this.LayoutSettings.CellHorizontalSpacing);
else
ci.MaxWidth = Math.Max(ci.MaxWidth, cell.BoundsRelative.Width + this.LayoutSettings.CellHorizontalSpacing);
}
x += Math.Max(0, cell.BoundsRelative.Width);
width += Math.Max(0, cell.BoundsRelative.Width);
//if(cell.BoundsRelative.Width>0)
{
x += this.LayoutSettings.CellHorizontalSpacing;
width += this.LayoutSettings.CellHorizontalSpacing;
}
if (cell.BoundsRelative.Height > height)
{
if (height != 0) adjustHeight = true;
height = cell.BoundsRelative.Height;
}
else if (!firstVisible && cell.BoundsRelative.Height < height && !cell.TextContentBounds.IsEmpty)
adjustHeight = true;
firstVisible = false;
}
}
// Apply the uniform cell text height to all cells
if (adjustHeight)
{
for (int i = 0; i < node.Cells.Count; i++)
{
Cell cell = node.Cells[i];
if (cell.BoundsRelative.Height != height && !cell.TextContentBounds.IsEmpty)
{
cell.TextContentBounds = new Rectangle(cell.TextContentBounds.X, cell.TextContentBounds.Y,
cell.TextContentBounds.Width, cell.TextContentBounds.Height + (height - cell.BoundsRelative.Height));
int diff = height - cell.BoundsRelative.Height;
if (!cell.CheckBoxBoundsRelative.IsEmpty)
{
eVerticalAlign va = GetCheckBoxVerticalAlign(cell.CheckBoxAlignment, layoutInfo.View);
if (va == eVerticalAlign.Middle)
cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X, cell.CheckBoxBoundsRelative.Y + (int)Math.Ceiling((double)diff / 2), cell.CheckBoxBoundsRelative.Width, cell.CheckBoxBoundsRelative.Height));
if (va == eVerticalAlign.Bottom)
cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X, cell.CheckBoxBoundsRelative.Y + diff, cell.CheckBoxBoundsRelative.Width, cell.CheckBoxBoundsRelative.Height));
}
if (!cell.ImageBoundsRelative.IsEmpty)
{
eVerticalAlign va = GetVerticalAlign(cell.ImageAlignment, layoutInfo.View);
if(va== eVerticalAlign.Middle)
cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X, cell.ImageBoundsRelative.Y + (int)Math.Ceiling((double)diff / 2), cell.ImageBoundsRelative.Width, cell.ImageBoundsRelative.Height));
else if (va == eVerticalAlign.Bottom)
cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X, cell.ImageBoundsRelative.Y + diff, cell.ImageBoundsRelative.Width, cell.ImageBoundsRelative.Height));
}
cell.SetBounds(new Rectangle(cell.BoundsRelative.X, cell.BoundsRelative.Y, cell.BoundsRelative.Width, height));
}
}
}
// Take last added spacing off
x -= this.LayoutSettings.CellHorizontalSpacing;
width -= this.LayoutSettings.CellHorizontalSpacing;
return new Size(width,height);
}
protected virtual Size LayoutCellsVertical(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
eHorizontalAlign align = node.VerticalCellLayoutAlignment; // eHorizontalAlign.Center;
int iVisibleCells=0;
int cellCount = node.Cells.Count;
for(int i=0;i<cellCount;i++)
{
Cell cell = null;
if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count == cellCount)
cell = node.Cells[layoutInfo.ChildColumns.ColumnInfo[i].AbsoluteIndex];
else if(layoutInfo.DefaultColumns.ColumnInfo.Count == cellCount)
cell = node.Cells[layoutInfo.DefaultColumns.ColumnInfo[i].AbsoluteIndex];
else
cell = node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(cell.Layout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(cell.Layout==eCellPartLayout.Vertical);
else if(layoutInfo.CellPartLayout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(layoutInfo.CellPartLayout==eCellPartLayout.Vertical);
if (layoutInfo.DefaultColumns.ColumnInfo.Count > 0 || layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0)
{
ColumnInfo ci=null;
if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0)
ci=layoutInfo.ChildColumns.ColumnInfo[i] as ColumnInfo;
else
ci=layoutInfo.DefaultColumns.ColumnInfo[i] as ColumnInfo;
bCellVisible=ci.Visible;
cellLayout.CellWidth=ci.Width;
}
else if (layoutInfo.View == eView.Tile)
{
cellLayout.CellWidth = layoutInfo.TileSize.Width;
cellLayout.CellHeight = layoutInfo.TileSize.Height;
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
this.LayoutSingleCell(cellLayout);
cell.SetVisible(bCellVisible);
if(bCellVisible)
{
iVisibleCells++;
y+=cell.BoundsRelative.Height;
height+=cell.BoundsRelative.Height;
if(cell.BoundsRelative.Height>0)
{
y+=this.CellVerticalSpacing;
height+=this.CellVerticalSpacing;
}
if(cell.BoundsRelative.Width>width)
width=cell.BoundsRelative.Width;
}
}
// Take last added spacing off
y-=this.CellVerticalSpacing;
height-=this.CellVerticalSpacing;
// Additional pass needed if horizontal alignment is other than left and there is more than one cell visible
if(align!=eHorizontalAlign.Left && iVisibleCells>1)
{
foreach(Cell cell in node.Cells)
{
if(!cell.IsVisible)
continue;
if(align==eHorizontalAlign.Center)
this.Offset(cell,(width-cell.BoundsRelative.Width)/2,0);
else // Right aligned cells
this.Offset(cell,width-cell.BoundsRelative.Width,0);
}
}
return new Size(width,height);
}
private LayoutCellInfo m_LayoutCellInfo=null;
protected virtual LayoutCellInfo GetLayoutCellInfo()
{
if(m_LayoutCellInfo==null)
m_LayoutCellInfo=new LayoutCellInfo();
return m_LayoutCellInfo;
}
protected virtual bool HasImage(Cell cell)
{
if (cell.Images.Image != null || cell.Images.ImageIndex >= 0 || !string.IsNullOrEmpty(cell.Images.ImageKey))
return true;
return false;
}
}
}
internal class LayoutCellInfo
{
public Cell ContextCell=null;
public int CellWidth=0;
public int CellHeight = 0;
public System.Drawing.Graphics Graphics=null;
public int Left=0;
public int Top=0;
public ElementStyle LayoutStyle=null;
public bool LeftToRight=true;
public bool VerticalPartAlignment=false;
public eView View = eView.Tree;
public int CellIndex = 0;
private Font _Font;
public Font Font
{
get { return _Font; }
set
{
if (_Font != value)
{
_Font = value;
if (_Font != null)
FontHeight = _Font.Height;
else
FontHeight = 0;
}
}
}
public int FontHeight = 0;
public LayoutCellInfo()
{
}
}
internal class ColumnInfo
{
public bool Visible;
public int Width;
public int MaxWidth = 0;
public ColumnHeader ColumnHeader = null;
public bool AutoSize = false;
// Specifies the absolute index for column data. AbsoluteIndex may be different from DisplayIndex of columns are re-arranged
public int AbsoluteIndex = -1;
public ColumnInfo(int width, bool visible, ColumnHeader h, int absoluteIndex)
{
this.Width=width;
this.Visible=visible;
this.ColumnHeader = h;
this.AutoSize = h.Width.AutoSize;
this.AbsoluteIndex = absoluteIndex;
}
}
}

View File

@ -0,0 +1,702 @@
using System;
using System.Drawing;
using System.Collections;
using DevComponents.DotNetBar;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Collections.Generic;
namespace DevComponents.AdvTree.Layout
{
/// <summary>
/// Summary description for NodeLayout.
/// </summary>
internal abstract class NodeLayout
{
#region Private Variables
protected int m_Height=0;
protected int m_Width=0;
protected AdvTree m_Tree=null;
protected Rectangle m_ClientArea;
//protected int m_ExpandAreaWidth=8;
protected Size m_ExpandPartSize=new Size(8,8);
private Size _CachedExpandPartSize = Size.Empty;
private int m_CommandAreaWidth=10;
private int m_TreeLayoutChildNodeIndent = 16;
private System.Windows.Forms.LeftRightAlignment m_LeftRight=System.Windows.Forms.LeftRightAlignment.Left;
private int m_NodeVerticalSpacing=3;
private int m_NodeHorizontalSpacing=0;
private CellLayout m_CellLayout=null;
private Graphics m_Graphics=null;
#endregion
public NodeLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings)
{
m_Tree=treeControl;
m_ClientArea=clientArea;
_LayoutSettings = layoutSettings;
}
/// <summary>
/// Performs layout of the nodes inside of the tree control.
/// </summary>
public virtual void PerformLayout()
{
}
public virtual void UpdateTopLevelColumnsWidth()
{
}
private LayoutSettings _LayoutSettings;
/// <summary>
/// Gets or sets layout settings.
/// </summary>
public LayoutSettings LayoutSettings
{
get { return _LayoutSettings; }
set { _LayoutSettings = value; }
}
/// <summary>
/// Performs layout for single unassigned node. Node does not have to be part of the tree control.
/// </summary>
/// <param name="node">Node to perform layout on.</param>
public virtual void PerformSingleNodeLayout(Node node)
{
if(node==null)
return;
this.PrepareStyles();
// Get default Columns
System.Drawing.Graphics g=this.GetGraphics();
SmoothingMode sm = g.SmoothingMode;
TextRenderingHint th = g.TextRenderingHint;
if (m_Tree.AntiAlias)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
}
try
{
NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(g);
layoutInfo.ContextNode=node;
if (node.IsDragNode)
layoutInfo.DefaultColumns = new NodeColumnInfo(new List<ColumnInfo>(), false);
LayoutNode(layoutInfo);
}
finally
{
if (m_Tree.AntiAlias)
{
g.SmoothingMode = sm;
//g.TextRenderingHint = th;
}
g.Dispose();
}
}
public int Width
{
get {return m_Width;}
}
public int Height
{
get {return m_Height;}
}
public Rectangle ClientArea
{
get {return m_ClientArea;}
set {m_ClientArea=value;}
}
public Graphics Graphics
{
get { return m_Graphics;}
set { m_Graphics = value;}
}
internal bool DisposeGraphics
{
get
{
return (m_Graphics == null);
}
}
protected virtual System.Drawing.Graphics GetGraphics()
{
if(m_Graphics!=null)
return m_Graphics;
Graphics g=m_Tree.CreateGraphics();
return g;
}
/// <summary>
/// Resizes all styles and prepares them for layout.
/// </summary>
protected virtual void PrepareStyles()
{
// Resize styles if needed
foreach(ElementStyle es in m_Tree.Styles)
{
if(es.SizeChanged)
ElementStyleLayout.CalculateStyleSize(es,m_Tree.Font);
}
if (_LayoutSettings != null)
_CachedExpandPartSize = Dpi.Size(_LayoutSettings.ExpandPartSize);
else
_CachedExpandPartSize = Dpi.Size(m_ExpandPartSize);
}
/// <summary>
/// Returns default top-level columns for tree control.
/// </summary>
/// <returns>Returns array list of ColumnInfo objects.</returns>
protected virtual NodeColumnInfo GetDefaultColumnInfo()
{
List<ColumnInfo> ci = new List<ColumnInfo>();
NodeColumnInfo info = new NodeColumnInfo(ci, false);
ColumnHeaderCollection columns=m_Tree.Columns;
//int treeWidth = m_Tree.ClientRectangle.Width;
if(columns!=null)
{
for (int i = 0; i < columns.Count; i++)
{
int columnIndex = columns.DisplayIndexMap[i];
ColumnHeader h = columns[columnIndex];
ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex);
ci.Add(columnInfo);
info.HasAutoSizeColumn |= columnInfo.AutoSize;
}
}
return info;
}
/// <summary>
/// Returns column information for a given node.
/// </summary>
/// <param name="node">Node to return column information for</param>
/// <returns>Returns array list of ColumnInfo objects or null if there are no columns defined.</returns>
protected virtual NodeColumnInfo GetNodeColumnInfo(Node node)
{
if (!node.HasColumns)
{
return null;
}
List<ColumnInfo> ci = new List<ColumnInfo>();
NodeColumnInfo info = new NodeColumnInfo(ci, false);
ColumnHeaderCollection columns = node.NodesColumns;
for (int i = 0; i < columns.Count; i++)
{
int columnIndex = columns.DisplayIndexMap[i];
ColumnHeader h = columns[columnIndex];
ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex);
ci.Add(columnInfo);
info.HasAutoSizeColumn |= columnInfo.AutoSize;
}
return info;
}
///// <summary>
///// Gets or sets the vertical spacing between nodes in pixels.
///// </summary>
//public virtual int NodeVerticalSpacing
//{
// get {return m_NodeVerticalSpacing;}
// set {m_NodeVerticalSpacing=value;}
//}
///// <summary>
///// Gets or sets the horizontal spacing between nodes in pixels.
///// </summary>
//public virtual int NodeHorizontalSpacing
//{
// get {return m_NodeHorizontalSpacing;}
// set {m_NodeHorizontalSpacing=value;}
//}
/// <summary>
/// Gets or sets the child node indent in pixels.
/// </summary>
public virtual int TreeLayoutChildNodeIndent
{
get {return m_TreeLayoutChildNodeIndent; }
set { m_TreeLayoutChildNodeIndent = value; }
}
/// <summary>
/// Returns column header collection for the given column template name.
/// </summary>
/// <param name="name">Name of the column template.</param>
/// <returns>Column header collection or null if template name cannot be found.</returns>
public virtual ColumnHeaderCollection GetColumnHeader(string name)
{
if(name=="" || name==null)
return null;
return m_Tree.Headers.GetByName(name).Columns;
}
//private int _ExpandAreaWidth = 24;
///// <summary>
///// Returns width of the expand button area. Default is 24 pixels.
///// </summary>
//public virtual int ExpandAreaWidth
//{
// get { return _ExpandAreaWidth; }
// set
// {
// _ExpandAreaWidth = value;
// }
//}
///// <summary>
///// Gets or sets width of command button area. Default is 8 pixels.
///// </summary>
//public virtual int CommandAreaWidth
//{
// get {return m_CommandAreaWidth;}
// set {m_CommandAreaWidth=value;}
//}
/// <summary>
/// Sets the position and size of the node command button.
/// </summary>
/// <param name="layoutInfo">Node layout context information</param>
protected virtual void LayoutCommandPart(NodeLayoutContextInfo layoutInfo, ElementStyle nodeStyle)
{
// Command part is right-aligned just before the node border
Rectangle bounds = new Rectangle(layoutInfo.ContextNode.ContentBounds.Right - this.LayoutSettings.CommandAreaWidth -
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y+
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top),
this.LayoutSettings.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height -
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top)-
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Bottom));
// Rectangle bounds=new Rectangle(layoutInfo.ContextNode.ContentBounds.Right-this.CommandAreaWidth-
// ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y,
// this.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height);
layoutInfo.ContextNode.CommandBoundsRelative=bounds;
}
/// <summary>
/// Determines the rectangle of the +/- part of the tree node that is used to expand node.
/// </summary>
/// <param name="layoutInfo">Node layout context information</param>
protected virtual void LayoutExpandPart(NodeLayoutContextInfo layoutInfo, bool bLeftNode, int x)
{
Node node=layoutInfo.ContextNode;
Size partSize=GetExpandPartSize();
Rectangle bounds=new Rectangle(x,0,partSize.Width,partSize.Height);
if (node.ExpandPartVerticalAlignment == eVerticalAlign.Middle)
bounds.Y = (node.BoundsRelative.Height - bounds.Height) / 2;
else if (node.ExpandPartVerticalAlignment == eVerticalAlign.Top)
bounds.Y = Dpi.Height3;
else
bounds.Y = node.BoundsRelative.Height - partSize.Height - Dpi.Height3;
if (bLeftNode || layoutInfo.ExpandPartAlignedLeft && layoutInfo.LeftToRight)
bounds.X += (layoutInfo.ExpandAreaWidth - bounds.Width) / 2;
else
bounds.X = node.BoundsRelative.Right - layoutInfo.ExpandAreaWidth + (layoutInfo.ExpandAreaWidth - partSize.Width) / 2;
node.SetExpandPartRectangle(bounds);
}
/// <summary>
/// Returns the size of the node expand part.
/// </summary>
/// <returns>Size of the expand part, default 8,8.</returns>
protected virtual Size GetExpandPartSize()
{
return _CachedExpandPartSize;
//if (_LayoutSettings != null)
// return _LayoutSettings.ExpandPartSize;
//return m_ExpandPartSize;
}
///// <summary>
///// Gets or sets the size of the expand part that is expanding/collapsing the node. Default value is 8,8.
///// </summary>
//public System.Drawing.Size ExpandPartSize
//{
// get {return m_ExpandPartSize;}
// set {m_ExpandPartSize=value;}
//}
/// <summary>
/// Provides the layout for single node.
/// </summary>
/// <param name="layoutInfo">Layout information.</param>
protected virtual void LayoutNode(NodeLayoutContextInfo layoutInfo)
{
bool bHasExpandPart=this.HasExpandPart(layoutInfo);
bool bHasCommandPart=this.HasCommandPart(layoutInfo);
Node node=layoutInfo.ContextNode;
Rectangle nodeRect = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0);
Rectangle nodeContentRect=Rectangle.Empty; // Node content rect excludes expand rect
int height=0, width=0;
// Left node relative to the main root node...
bool bLeftNode = layoutInfo.LeftToRight; // (layoutInfo.MapPositionNear && layoutInfo.LeftToRight);
layoutInfo.LayoutNodeExpandPartWidth = 0;
if(bLeftNode && bHasExpandPart || this.ReserveExpandPartSpace)
{
layoutInfo.LayoutNodeExpandPartWidth = (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing);
width += (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing);
}
int x=width; // relative to 0,0 of the node
int y=0; // Relative to 0,0 of the node
// Apply node style
ElementStyle nodeStyle=null;
if(node.Expanded && node.StyleExpanded!=null)
nodeStyle=node.StyleExpanded;
else if(node.Style!=null)
nodeStyle=node.Style;
else
nodeStyle=layoutInfo.DefaultNodeStyle;
nodeContentRect.X=x;
if(nodeStyle!=null)
{
x+=ElementStyleLayout.LeftWhiteSpace(nodeStyle);
y+=ElementStyleLayout.TopWhiteSpace(nodeStyle);
nodeContentRect.X+=nodeStyle.MarginLeft;
nodeContentRect.Y+=nodeStyle.MarginTop;
}
Size size = this.GetCellLayout().LayoutCells(layoutInfo, x, y);
node.SetCellsBounds(new Rectangle(x, y, size.Width, size.Height));
height=size.Height;
width+=size.Width;
nodeContentRect.Width=size.Width;
nodeContentRect.Height=size.Height;
if(nodeStyle!=null)
{
nodeContentRect.Width+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Left)+
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Right));
nodeContentRect.Height+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Top)+
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Bottom));
width+=(ElementStyleLayout.HorizontalStyleWhiteSpace(nodeStyle));
height+=(ElementStyleLayout.VerticalStyleWhiteSpace(nodeStyle));
}
if (!bLeftNode && bHasExpandPart && !this.ReserveExpandPartSpace)
width += layoutInfo.ExpandAreaWidth;
if(bHasCommandPart)
{
width += this.LayoutSettings.CommandAreaWidth;
nodeContentRect.Width += this.LayoutSettings.CommandAreaWidth;
}
nodeRect.Height=height;
nodeRect.Width=width;
node.SetBounds(nodeRect);
node.SetContentBounds(nodeContentRect);
if(bHasCommandPart)
LayoutCommandPart(layoutInfo, nodeStyle);
else
node.CommandBoundsRelative=Rectangle.Empty;
if (bHasExpandPart || this.ReserveExpandPartSpace)
LayoutExpandPart(layoutInfo,bLeftNode, 0);
else
node.SetExpandPartRectangle(Rectangle.Empty);
node.SizeChanged=false;
// Calculate size and location of node column header if any
//if(node.NodesColumnHeaderVisible)
{
//layoutInfo.Left+=this.NodeLevelOffset;
LayoutColumnHeader(layoutInfo);
//layoutInfo.Left-=this.NodeLevelOffset;
}
}
/// <summary>
/// Returns true if given node has expand part.
/// </summary>
/// <param name="layoutInfo">Layout context information.</param>
/// <returns></returns>
protected virtual bool HasExpandPart(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if(node.ExpandVisibility==eNodeExpandVisibility.Auto)
{
if(IsRootNode(node) && !RootHasExpandedPart || !NodeOperations.GetAnyVisibleNodes(node))
return false;
return true;
}
else
return (node.ExpandVisibility==eNodeExpandVisibility.Visible);
}
/// <summary>
/// Returns whether given node has command part.
/// </summary>
/// <param name="layoutInfo">Layout context information.</param>
/// <returns>True if command part should be drawn otherwise false.</returns>
protected virtual bool HasCommandPart(NodeLayoutContextInfo layoutInfo)
{
return layoutInfo.ContextNode.CommandButton;
}
/// <summary>
/// Returns true if root node should have expanded part
/// </summary>
protected virtual bool RootHasExpandedPart
{
get {return true;}
}
/// <summary>
/// Returns true if expand part space should be accounted for even if they expand part is not visible or need to be displayed. Default value is false.
/// </summary>
protected virtual bool ReserveExpandPartSpace
{
get
{
return false;
}
}
/// <summary>
/// Returns class responsible for cell layout.
/// </summary>
/// <returns>Cell layout class.</returns>
protected internal virtual CellLayout GetCellLayout()
{
if (m_CellLayout == null)
m_CellLayout = new CellLayout(this.LayoutSettings);
return m_CellLayout;
}
/// <summary>
/// Offsets node location and location of it's child nodes bounds.
/// </summary>
/// <param name="node">Node to offset.</param>
/// <param name="x">Horizontal offset.</param>
/// <param name="y">Vertical offset.</param>
protected virtual void OffsetNodeLocation(Node node, int x, int y)
{
node.SetBounds(new Rectangle(node.BoundsRelative.X+x,node.BoundsRelative.Y+y,node.BoundsRelative.Width,node.BoundsRelative.Height));
if(node.Expanded)
node.ChildNodesBounds=new Rectangle(node.ChildNodesBounds.X+x,node.ChildNodesBounds.Y+y,node.ChildNodesBounds.Width,node.ChildNodesBounds.Height);
}
protected virtual NodeLayoutContextInfo GetDefaultNodeLayoutContextInfo(System.Drawing.Graphics graphics)
{
NodeLayoutContextInfo layoutInfo=new NodeLayoutContextInfo();
layoutInfo.ClientRectangle=m_ClientArea;
layoutInfo.DefaultColumns=this.GetDefaultColumnInfo();
layoutInfo.ChildColumns=null;
layoutInfo.Indent = m_Tree.Indent;
layoutInfo.Left=0;
layoutInfo.Top=0;
layoutInfo.LeftMargin = m_Tree.BackgroundStyle.PaddingLeft;
layoutInfo.DefaultFont=m_Tree.Font;
layoutInfo.LeftToRight=(this.LeftRight==System.Windows.Forms.LeftRightAlignment.Left);
layoutInfo.Graphics=graphics;
layoutInfo.Styles=m_Tree.Styles;
layoutInfo.FullRowBackgroundNodes = new ArrayList();
if(m_Tree.CellLayout!=eCellLayout.Default)
layoutInfo.CellLayout=m_Tree.CellLayout;
if(m_Tree.CellPartLayout!=eCellPartLayout.Default)
layoutInfo.CellPartLayout=m_Tree.CellPartLayout;
if(m_Tree.NodeStyle!=null)
layoutInfo.DefaultNodeStyle=m_Tree.NodeStyle;
if(m_Tree.CellStyleDefault!=null)
layoutInfo.DefaultCellStyle=m_Tree.CellStyleDefault;
else
layoutInfo.DefaultCellStyle=ElementStyle.GetDefaultCellStyle(layoutInfo.DefaultNodeStyle);
// Determine size of the default Column Header
if(m_Tree.ColumnStyleNormal!=null)
{
ElementStyleLayout.CalculateStyleSize(m_Tree.ColumnStyleNormal,layoutInfo.DefaultFont);
layoutInfo.DefaultHeaderSize=m_Tree.ColumnStyleNormal.Size;
}
if(layoutInfo.DefaultHeaderSize.IsEmpty)
layoutInfo.DefaultHeaderSize.Height=layoutInfo.DefaultFont.Height+4;
layoutInfo.ExpandPartWidth = Dpi.Width(this.Tree.ExpandWidth);
layoutInfo.View = this.Tree.View;
layoutInfo.TileSize = Dpi.Size(this.Tree.TileSize);
layoutInfo.ColumnStyle = this.Tree.ColumnStyleNormal;
layoutInfo.ExpandAreaWidth = Dpi.Width(this.LayoutSettings.ExpandAreaWidth);
return layoutInfo;
}
protected Node[] GetTopLevelNodes()
{
if(m_Tree.DisplayRootNode!=null)
return new Node[] {m_Tree.DisplayRootNode};
else
{
Node[] nodes=new Node[m_Tree.Nodes.Count];
m_Tree.Nodes.CopyTo(nodes);
return nodes;
}
}
protected bool IsRootNode(Node node)
{
return NodeOperations.IsRootNode(m_Tree,node);
}
protected virtual void EmptyBoundsUnusedNodes(Node[] topLevelNodes)
{
if(m_Tree.DisplayRootNode!=null)
{
Node node=m_Tree.DisplayRootNode.PrevVisibleNode;
while(node!=null)
{
node.SetBounds(Rectangle.Empty);
node=node.PrevVisibleNode;
}
node=m_Tree.DisplayRootNode.NextNode;
if(node==null)
{
node=m_Tree.DisplayRootNode.Parent;
while(node!=null)
{
if(node.NextNode!=null)
{
node=node.NextNode;
break;
}
else
node=node.Parent;
}
}
while(node!=null)
{
node.SetBounds(Rectangle.Empty);
node=node.NextVisibleNode;
}
}
else
{
for(int i=1;i<topLevelNodes.Length;i++)
{
topLevelNodes[i].SetBounds(Rectangle.Empty);
}
}
}
public AdvTree Tree
{
get { return m_Tree; }
}
#region Column Support
// Assumes that layoutInfo is up-to-date and that Node that is connected with
// columns is already processed and it's size and location calculated.
// layoutInfo.Top member reflects the next position below the node
// layoutInfo.LevelOffset should reflect the X offset for the child nodes.
public void LayoutColumnHeader(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if (!node.HasColumns || !node.Expanded)
{
node.ColumnHeaderHeight = 0;
return;
}
int spacing = 2;
int x = layoutInfo.Left + this.NodeLevelOffset + node.NodesIndent;
int y=layoutInfo.ContextNode.BoundsRelative.Bottom + spacing;
bool bLeftNode=(layoutInfo.MapPositionNear && layoutInfo.LeftToRight);
int expandPartWidth = layoutInfo.ExpandAreaWidth;
int cellPartSpacing=GetCellLayout().CellPartSpacing;
if (!bLeftNode)
x += (expandPartWidth + cellPartSpacing);
int clientWidth = layoutInfo.ClientRectangle.Width - (layoutInfo.Left + expandPartWidth);
if (clientWidth <= 0)
clientWidth = layoutInfo.ClientRectangle.Width;
node.ColumnHeaderHeight = Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, x, y, clientWidth, this.GetCellLayout().LayoutSettings.CellHorizontalSpacing) + spacing;
if (!node.NodesColumnsHeaderVisible)
node.ColumnHeaderHeight = 0;
}
private int _NodeLevelOffset = 16;
internal int NodeLevelOffset
{
get { return _NodeLevelOffset; }
set
{
_NodeLevelOffset = value;
}
}
#endregion
#region RTL Support
public virtual System.Windows.Forms.LeftRightAlignment LeftRight
{
get {return m_LeftRight;}
set {m_LeftRight=value;}
}
#endregion
}
internal class NodeColumnInfo
{
/// <summary>
/// Initializes a new instance of the NodeColumnInfo structure.
/// </summary>
/// <param name="columnInfo"></param>
/// <param name="hasAutoSizeColumn"></param>
public NodeColumnInfo(List<ColumnInfo> columnInfo, bool hasAutoSizeColumn)
{
ColumnInfo = columnInfo;
HasAutoSizeColumn = hasAutoSizeColumn;
}
/// <summary>
/// Gets or sets the list of column info object for the columns.
/// </summary>
public List<ColumnInfo> ColumnInfo;
/// <summary>
/// Gets or sets whether columns have auto-size column.
/// </summary>
public bool HasAutoSizeColumn;
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Drawing;
using System.Collections;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Layout
{
/// <summary>
/// Used to pass node contextual information used for layout of the node.
/// </summary>
internal class NodeLayoutContextInfo
{
public Node ContextNode=null;
public Rectangle ClientRectangle=Rectangle.Empty;
public int Left;
public int Top;
public int LeftMargin = 0;
public NodeColumnInfo DefaultColumns=null;
public NodeColumnInfo ChildColumns = null;
public ElementStyle DefaultCellStyle=null;
public ElementStyle DefaultNodeStyle=null;
public Size DefaultHeaderSize=Size.Empty;
public bool LeftToRight=true;
public bool HasExpandPart=true;
public System.Drawing.Graphics Graphics=null;
public ElementStyleCollection Styles=null;
public eCellLayout CellLayout=eCellLayout.Default;
public eCellPartLayout CellPartLayout=eCellPartLayout.Horizontal;
public bool MapPositionNear=false;
public bool ExpandPartAlignedLeft = false;
public ColumnHeaderCollection TreeColumns = null;
public ArrayList FullRowBackgroundNodes = null;
public int ExpandPartWidth = 0;
public int CurrentLineHeight = 0; // Used by tile layout
public int CurrentLevelLeft = 0; // Used by tile layout
public eView View = eView.Tree; // Current control view
public Size TileSize = Size.Empty; // Tile size
public bool IsViewGroupping = false; // Tile view grouping enabled
public ElementStyle ColumnStyle = null;
public int LayoutNodeExpandPartWidth = 0;
public int Indent = 0;
public int ExpandAreaWidth = 0; // Cached LayoutSettings.ExpandAreaWidth with DPI multipler applied.
private Font _DefaultFont = null;
public Font DefaultFont
{
get { return _DefaultFont; }
set
{
if (_DefaultFont != value)
{
_DefaultFont = value;
if (_DefaultFont != null)
DefaultFontHeight = _DefaultFont.Height;
else
DefaultFontHeight = 0;
}
}
}
public int DefaultFontHeight = 0;
}
}

View File

@ -0,0 +1,393 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace DevComponents.AdvTree.Layout
{
/// <summary>
/// Performs ListView Tile style layout.
/// </summary>
internal class NodeTileLayout : NodeLayout
{
public NodeTileLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings)
: base(treeControl, clientArea, layoutSettings)
{
}
public override void UpdateTopLevelColumnsWidth()
{
// Columns are not visible in tile layout
this.Tree.Columns.SetBounds(Rectangle.Empty);
}
/// <summary>
/// Returns default top-level columns for tree control.
/// </summary>
/// <returns>Returns array list of ColumnInfo objects.</returns>
protected override NodeColumnInfo GetDefaultColumnInfo()
{
// There are no columns in Tile view
List<ColumnInfo> ci = new List<ColumnInfo>();
NodeColumnInfo info = new NodeColumnInfo(ci, false);
return info;
}
protected override NodeLayoutContextInfo GetDefaultNodeLayoutContextInfo(System.Drawing.Graphics graphics)
{
NodeLayoutContextInfo context = base.GetDefaultNodeLayoutContextInfo(graphics);
context.IsViewGroupping = this.Groupping;
return context;
}
public override void PerformLayout()
{
this.PrepareStyles();
Rectangle area = Rectangle.Empty;
Graphics g=this.GetGraphics();
SmoothingMode sm = g.SmoothingMode;
TextRenderingHint th = g.TextRenderingHint;
if (m_Tree.AntiAlias)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
}
NodeLayoutContextInfo layoutInfo = GetDefaultNodeLayoutContextInfo(g);
layoutInfo.ExpandPartAlignedLeft = true;
layoutInfo.Left = ClientArea.X;
layoutInfo.Top = ClientArea.Y;
CellLayout cellLayout = this.GetCellLayout();
cellLayout.ResetCheckBoxSize();
if (this.Tree.CheckBoxImageChecked != null)
cellLayout.CheckBoxSize = this.Tree.CheckBoxImageChecked.Size;
LayoutTopLevelColumns(layoutInfo);
// Get default Columns
NodeColumnInfo defaultColInfoList = this.GetDefaultColumnInfo();
layoutInfo.DefaultColumns = defaultColInfoList;
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
int defaultTop = layoutInfo.Top;
area = ProcessTopLevelNodes(area, layoutInfo, topLevelNodes);
//if (defaultColInfoList.HasAutoSizeColumn)
//{
// foreach (ColumnInfo columnInfo in defaultColInfoList.ColumnInfo)
// {
// if (columnInfo.AutoSize)
// {
// columnInfo.AutoSize = false;
// columnInfo.Width = columnInfo.MaxWidth;
// columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth);
// columnInfo.MaxWidth = 0;
// }
// }
// layoutInfo.ContextNode = null;
// LayoutTopLevelColumns(layoutInfo);
// layoutInfo.Top = defaultTop;
// area = ProcessTopLevelNodes(Rectangle.Empty, layoutInfo, topLevelNodes);
//}
}
finally
{
if (m_Tree.AntiAlias)
{
g.SmoothingMode = sm;
//g.TextRenderingHint = th;
}
if(this.DisposeGraphics)
g.Dispose();
}
if (layoutInfo.FullRowBackgroundNodes.Count > 0)
Tree.FullRowBackgroundNodes = layoutInfo.FullRowBackgroundNodes;
else
Tree.FullRowBackgroundNodes = null;
m_Width = area.Width;
m_Height = area.Height;
}
private void LayoutTopLevelColumns(NodeLayoutContextInfo layoutInfo)
{
// There are no columns in Tile view
this.Tree.SetColumnHeaderControlVisibility(false);
}
private Rectangle ProcessTopLevelNodes(Rectangle area, NodeLayoutContextInfo layoutInfo, Node[] topLevelNodes)
{
layoutInfo.CurrentLevelLeft = layoutInfo.Left;
bool isPreviousGroupNode = false;
foreach (Node childNode in topLevelNodes)
{
layoutInfo.ContextNode = childNode;
if (childNode.Visible)
{
if (_Groupping && childNode.HasChildNodes)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
layoutInfo.Left = layoutInfo.CurrentLevelLeft;
isPreviousGroupNode = true;
}
else
{
if (isPreviousGroupNode)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
layoutInfo.Left = layoutInfo.CurrentLevelLeft;
}
isPreviousGroupNode = false;
}
}
ProcessNode(layoutInfo);
if (childNode.Visible)
{
area = Rectangle.Union(area, childNode.BoundsRelative);
if (childNode.Expanded && childNode.HasChildNodes)
area = Rectangle.Union(area, childNode.ChildNodesBounds);
if (!(_Groupping && childNode.HasChildNodes))
layoutInfo.Left += childNode.BoundsRelative.Width + this.LayoutSettings.NodeHorizontalSpacing;
}
}
return area;
}
private Rectangle ProcessChildNodes(NodeLayoutContextInfo layoutInfo, Node node, int nodeVerticalSpacing, NodeColumnInfo childColumns)
{
Rectangle childNodesBounds = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0);
bool isPreviousGroupNode = false;
foreach (Node childNode in node.Nodes)
{
if (!childNode.Visible) continue;
if (_Groupping && childNode.HasChildNodes)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
layoutInfo.Left = layoutInfo.CurrentLevelLeft;
isPreviousGroupNode = true;
}
else
{
if (isPreviousGroupNode)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
layoutInfo.Left = layoutInfo.CurrentLevelLeft;
isPreviousGroupNode = false;
}
}
layoutInfo.ContextNode = childNode;
layoutInfo.ChildColumns = childColumns;
ProcessNode(layoutInfo);
if (!(_Groupping && childNode.HasChildNodes))
layoutInfo.Left += childNode.BoundsRelative.Width + this.LayoutSettings.NodeHorizontalSpacing;
if (isPreviousGroupNode)
{
childNodesBounds.Width = Math.Max(childNodesBounds.Width,
Math.Max(childNode.BoundsRelative.Width, (childNode.Expanded && childNode.ChildNodesBounds.Width > 0 ? childNode.ChildNodesBounds.Right - childNodesBounds.X : 0)));
childNodesBounds.Height += childNode.BoundsRelative.Height + (childNode.Expanded ? childNode.ChildNodesBounds.Height + childNode.ColumnHeaderHeight : 0) + nodeVerticalSpacing;
}
else
{
childNodesBounds = Rectangle.Union(childNodesBounds, childNode.BoundsRelative);
childNodesBounds.Height += nodeVerticalSpacing;
}
}
return childNodesBounds;
}
#region Node routines
private void ProcessNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if (!node.Visible || node.Cells.Count == 0) return;
if (node.SizeChanged || _Groupping && node.HasChildNodes)
{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
}
if (node.FullRowBackground)
layoutInfo.FullRowBackgroundNodes.Add(node);
// Position the node
if (_Groupping && node.HasChildNodes)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
}
else
{
if (layoutInfo.Left + node.BoundsRelative.Width > this.ClientArea.Right)
{
layoutInfo.Left = layoutInfo.CurrentLevelLeft;
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
}
}
layoutInfo.CurrentLineHeight = Math.Max(layoutInfo.CurrentLineHeight, node.BoundsRelative.Height);
if (node.BoundsRelative.X != layoutInfo.Left || node.BoundsRelative.Y != layoutInfo.Top)
{
// Adjust top position
node.SetBounds(new Rectangle(layoutInfo.Left,layoutInfo.Top,node.BoundsRelative.Width,node.BoundsRelative.Height));
}
// Position the node
if (_Groupping && node.HasChildNodes)
{
if (layoutInfo.CurrentLineHeight > 0)
layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing;
layoutInfo.CurrentLineHeight = 0;
}
int nodeVerticalSpacing = this.LayoutSettings.NodeVerticalSpacing;
// Need to set the Top position properly
//layoutInfo.Top += (node.BoundsRelative.Height + nodeVerticalSpacing);
// No columns in tile view
//if (DevComponents.AdvTree.Display.NodeDisplay.HasColumnsVisible(node))
// layoutInfo.Top += node.ColumnHeaderHeight;
if(_Groupping && node.HasChildNodes && node.Expanded)
{
int originalLevelOffset=layoutInfo.Left;
int originalLevelLeft = layoutInfo.CurrentLevelLeft;
int childNodesTop = layoutInfo.Top;
layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent;
layoutInfo.CurrentLevelLeft = layoutInfo.Left;
NodeColumnInfo parentColumns = layoutInfo.ChildColumns;
NodeColumnInfo childColumns = GetNodeColumnInfo(node);
Rectangle childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns);
//if (childColumns != null && childColumns.HasAutoSizeColumn)
//{
// foreach (ColumnInfo columnInfo in childColumns.ColumnInfo)
// {
// if (columnInfo.AutoSize)
// {
// columnInfo.Width = columnInfo.MaxWidth;
// columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth);
// columnInfo.AutoSize = false;
// columnInfo.MaxWidth = 0;
// }
// }
// layoutInfo.Top = originalTop;
// layoutInfo.Left = originalLevelOffset;
// layoutInfo.ContextNode = node;
// layoutInfo.ChildColumns = null;
// LayoutNode(layoutInfo);
// layoutInfo.Top = childNodesTop;
// layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent;
// childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns);
//}
node.ChildNodesBounds = childNodesBounds;
layoutInfo.ChildColumns=parentColumns;
layoutInfo.ContextNode=node;
layoutInfo.Left=originalLevelOffset;
layoutInfo.CurrentLevelLeft = originalLevelLeft;
}
else
node.ChildNodesBounds = Rectangle.Empty;
}
/// <summary>
/// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout.
/// </summary>
/// <param name="node">Node to get expand part alignment for</param>
/// <returns>true if node expand part is aligned to the left in left-to-right layout.</returns>
private bool ExpandPartAlignedNear(Node node)
{
return true; // If changed LayoutExpandPart needs to be updated as well
}
/// <summary>
/// Returns column information for a given node.
/// </summary>
/// <param name="node">Node to return column information for</param>
/// <returns>Returns array list of ColumnInfo objects or null if there are no columns defined.</returns>
protected override NodeColumnInfo GetNodeColumnInfo(Node node)
{
// No columns in tile-view
return null;
}
/// <summary>
/// Returns true if expand part space should be accounted for even if they expand part is not visible or need to be displayed. Default value is false.
/// </summary>
protected override bool ReserveExpandPartSpace
{
get
{
return false;
}
}
/// <summary>
/// Returns true if given node has expand part.
/// </summary>
/// <param name="layoutInfo">Layout context information.</param>
/// <returns></returns>
protected override bool HasExpandPart(NodeLayoutContextInfo layoutInfo)
{
Node node = layoutInfo.ContextNode;
if (node.ExpandVisibility == eNodeExpandVisibility.Auto)
{
if (!_Groupping || !NodeOperations.GetAnyVisibleNodes(node))
return false;
return true;
}
else
return (node.ExpandVisibility == eNodeExpandVisibility.Visible);
}
private bool _Groupping = true;
/// <summary>
/// Gets or sets whether parent/child node relationship is displayed as groups.
/// </summary>
public bool Groupping
{
get { return _Groupping; }
set
{
_Groupping = value;
}
}
private CellTileLayout _CellLayout = null;
/// <summary>
/// Returns class responsible for cell layout.
/// </summary>
/// <returns>Cell layout class.</returns>
protected internal override CellLayout GetCellLayout()
{
if (_CellLayout == null)
_CellLayout = new CellTileLayout(this.LayoutSettings);
return _CellLayout;
}
#endregion
}
}

View File

@ -0,0 +1,328 @@
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using System;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree.Layout
{
/// <summary>
/// Performs classic TreeView layout.
/// </summary>
internal class NodeTreeLayout:NodeLayout
{
public NodeTreeLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings)
: base(treeControl, clientArea, layoutSettings)
{
}
public override void UpdateTopLevelColumnsWidth()
{
if (this.Tree.Columns.Count > 0)
{
Rectangle columnsBounds = DevComponents.DotNetBar.ElementStyleLayout.GetInnerRect(this.Tree.BackgroundStyle, this.Tree.ClientRectangle);
if (this.Tree.VScrollBar != null) columnsBounds.Width -= this.Tree.VScrollBar.Width;
columnsBounds.Height = this.Tree.Columns.Bounds.Height;
if(this.Tree.Columns.Bounds.Width<columnsBounds.Width)
this.Tree.Columns.SetBounds(columnsBounds);
}
}
public override void PerformLayout()
{
this.PrepareStyles();
Rectangle area = Rectangle.Empty;
Graphics g=this.GetGraphics();
SmoothingMode sm = g.SmoothingMode;
TextRenderingHint th = g.TextRenderingHint;
if (m_Tree.AntiAlias)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
}
NodeLayoutContextInfo layoutInfo = GetDefaultNodeLayoutContextInfo(g);
layoutInfo.ExpandPartAlignedLeft = true;
layoutInfo.Left = ClientArea.X;
layoutInfo.Top = ClientArea.Y;
CellLayout cellLayout = this.GetCellLayout();
cellLayout.ResetCheckBoxSize();
if (this.Tree.CheckBoxImageChecked != null)
cellLayout.CheckBoxSize = this.Tree.CheckBoxImageChecked.Size;
LayoutTopLevelColumns(layoutInfo);
// Get default Columns
NodeColumnInfo defaultColInfoList = this.GetDefaultColumnInfo();
layoutInfo.DefaultColumns = defaultColInfoList;
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
int defaultTop = layoutInfo.Top;
area = ProcessTopLevelNodes(area, layoutInfo, topLevelNodes);
bool hasMinColumnAutoSizeWidth = false;
bool hasStretchToFillColumn = false;
if (defaultColInfoList.HasAutoSizeColumn)
{
foreach (ColumnInfo columnInfo in defaultColInfoList.ColumnInfo)
{
if (columnInfo.AutoSize)
{
columnInfo.AutoSize = false;
//if (columnInfo.ColumnHeader.Width.AutoSizeMinHeader)
//{
// columnInfo.Width = Math.Max(columnInfo.MaxWidth, columnInfo.Width);
// columnInfo.MaxWidth = Math.Max(columnInfo.MaxWidth, columnInfo.Width);
//}
//else
columnInfo.Width = columnInfo.MaxWidth;
columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth);
columnInfo.MaxWidth = 0;
if (columnInfo.ColumnHeader.Width.AutoSizeMinHeader)
hasMinColumnAutoSizeWidth = true;
if (columnInfo.ColumnHeader.StretchToFill)
hasStretchToFillColumn = true;
}
}
layoutInfo.ContextNode = null;
LayoutTopLevelColumns(layoutInfo);
// Adjust the of auto sized columns in case minimum header width is used
if (hasMinColumnAutoSizeWidth || hasStretchToFillColumn)
{
foreach (ColumnInfo columnInfo in defaultColInfoList.ColumnInfo)
{
if (columnInfo.ColumnHeader.Width.AutoSize && columnInfo.ColumnHeader.Width.AutoSizeMinHeader || columnInfo.ColumnHeader.StretchToFill)
{
columnInfo.Width = columnInfo.ColumnHeader.Bounds.Width;
}
}
}
layoutInfo.Top = defaultTop;
area = ProcessTopLevelNodes(Rectangle.Empty, layoutInfo, topLevelNodes);
}
}
finally
{
if (m_Tree.AntiAlias)
{
g.SmoothingMode = sm;
//g.TextRenderingHint = th;
}
if(this.DisposeGraphics)
g.Dispose();
}
if (layoutInfo.FullRowBackgroundNodes.Count > 0)
Tree.FullRowBackgroundNodes = layoutInfo.FullRowBackgroundNodes;
else
Tree.FullRowBackgroundNodes = null;
//if (columnsVisible && layoutInfo.DefaultColumns != null && layoutInfo.DefaultColumns.Count > 0)
//{
// bool layoutColumns = false;
// for (int i = 0; i < layoutInfo.DefaultColumns.Count; i++)
// {
// ColumnInfo ci = (ColumnInfo)layoutInfo.DefaultColumns[i];
// if (ci.Width == 0 && ci.MaxWidth > 0)
// {
// ci.ColumnHeader.ContentWidth = ci.MaxWidth;
// layoutColumns = true;
// }
// }
// if (layoutColumns)
// {
// layoutInfo.ContextNode = null;
// layoutInfo.TreeColumns = this.Tree.Columns;
// Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, ClientArea.X,
// ClientArea.Y, ClientArea.Width, this.GetCellLayout().CellHorizontalSpacing);
// }
//}
m_Width = area.Width;
m_Height = area.Height;
}
private void LayoutTopLevelColumns(NodeLayoutContextInfo layoutInfo)
{
// Layout tree columns
if (this.Tree.Columns.Count > 0)
{
Rectangle columnsBounds = m_ClientArea;// DevComponents.DotNetBar.ElementStyleLayout.GetInnerRect(this.Tree.BackgroundStyle, this.Tree.ClientRectangle);
//if (this.Tree.VScrollBar != null) columnsBounds.Width -= this.Tree.VScrollBar.Width;
layoutInfo.TreeColumns = this.Tree.Columns;
int columnHeight = Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, 0,
0, columnsBounds.Width, this.GetCellLayout().LayoutSettings.CellHorizontalSpacing);
columnHeight += this.LayoutSettings.NodeVerticalSpacing;
if (this.Tree.ColumnsVisible)
{
Rectangle headerBounds = layoutInfo.TreeColumns.Bounds;
if (headerBounds.Width > 0 && headerBounds.Width < columnsBounds.Width)
{
headerBounds.Width = columnsBounds.Width;
layoutInfo.TreeColumns.SetBounds(headerBounds);
}
layoutInfo.Top += columnHeight;
this.Tree.SetColumnHeaderControlVisibility(true);
}
else
this.Tree.SetColumnHeaderControlVisibility(false);
layoutInfo.TreeColumns = null;
}
else
this.Tree.SetColumnHeaderControlVisibility(false);
}
private Rectangle ProcessTopLevelNodes(Rectangle area, NodeLayoutContextInfo layoutInfo, Node[] topLevelNodes)
{
foreach (Node childNode in topLevelNodes)
{
layoutInfo.ContextNode = childNode;
ProcessNode(layoutInfo);
if (childNode.Visible)
{
area = Rectangle.Union(area, childNode.BoundsRelative);
if (childNode.Expanded)
area = Rectangle.Union(area, childNode.ChildNodesBounds);
}
}
return area;
}
#region Node routines
private void ProcessNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if (!node.Visible) return;
int originalTop = layoutInfo.Top;
if (node.SizeChanged || node.HasColumns || layoutInfo.DefaultColumns!=null && layoutInfo.DefaultColumns.HasAutoSizeColumn || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.HasAutoSizeColumn)
{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
}
if (node.FullRowBackground)
layoutInfo.FullRowBackgroundNodes.Add(node);
if (node.BoundsRelative.X != layoutInfo.Left || node.BoundsRelative.Y != layoutInfo.Top)
{
// Adjust top position
node.SetBounds(new Rectangle(layoutInfo.Left,layoutInfo.Top,node.BoundsRelative.Width,node.BoundsRelative.Height));
//foreach(Cell c in node.Cells)
// c.SetBounds(new Rectangle(c.BoundsRelative.X + layoutInfo.Left, c.BoundsRelative.Y+layoutInfo.Top, c.BoundsRelative.Width, c.BoundsRelative.Height));
}
int nodeVerticalSpacing = this.LayoutSettings.NodeVerticalSpacing;
// Need to set the Top position properly
layoutInfo.Top += (node.BoundsRelative.Height + nodeVerticalSpacing);
if (DevComponents.AdvTree.Display.NodeDisplay.HasColumnsVisible(node))
layoutInfo.Top += node.ColumnHeaderHeight;
if(node.Expanded)
{
int originalLevelOffset=layoutInfo.Left;
int childNodesTop = layoutInfo.Top;
layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent;
NodeColumnInfo parentColumns = layoutInfo.ChildColumns;
NodeColumnInfo childColumns = GetNodeColumnInfo(node);
Rectangle childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns);
if (childColumns != null && childColumns.HasAutoSizeColumn)
{
bool hasMinColumnAutoSizeWidth = false;
foreach (ColumnInfo columnInfo in childColumns.ColumnInfo)
{
if (columnInfo.AutoSize)
{
columnInfo.Width = columnInfo.MaxWidth;
columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth);
columnInfo.AutoSize = false;
columnInfo.MaxWidth = 0;
if (columnInfo.ColumnHeader.Width.AutoSizeMinHeader)
hasMinColumnAutoSizeWidth = true;
}
}
layoutInfo.Top = originalTop;
layoutInfo.Left = originalLevelOffset;
layoutInfo.ContextNode = node;
layoutInfo.ChildColumns = parentColumns;
LayoutNode(layoutInfo);
layoutInfo.Top = childNodesTop;
layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent;
// Adjust the of auto sized columns in case minimum header width is used
if (hasMinColumnAutoSizeWidth)
{
foreach (ColumnInfo columnInfo in childColumns.ColumnInfo)
{
if (columnInfo.ColumnHeader.Width.AutoSize && columnInfo.ColumnHeader.Width.AutoSizeMinHeader)
{
columnInfo.Width = columnInfo.ColumnHeader.Bounds.Width;
}
}
}
childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns);
}
node.ChildNodesBounds = childNodesBounds;
layoutInfo.ChildColumns=parentColumns;
layoutInfo.ContextNode=node;
layoutInfo.Left=originalLevelOffset;
}
}
private Rectangle ProcessChildNodes(NodeLayoutContextInfo layoutInfo, Node node, int nodeVerticalSpacing, NodeColumnInfo childColumns)
{
Rectangle childNodesBounds = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0);
foreach (Node childNode in node.Nodes)
{
if (!childNode.Visible) continue;
layoutInfo.ContextNode = childNode;
layoutInfo.ChildColumns = childColumns;
ProcessNode(layoutInfo);
childNodesBounds.Width = Math.Max(childNodesBounds.Width,
Math.Max(childNode.BoundsRelative.Width, (childNode.Expanded && childNode.ChildNodesBounds.Width > 0 ? childNode.ChildNodesBounds.Right - childNodesBounds.X : 0)));
childNodesBounds.Height += childNode.BoundsRelative.Height + (childNode.Expanded ? childNode.ChildNodesBounds.Height + childNode.ColumnHeaderHeight : 0) + nodeVerticalSpacing;
}
return childNodesBounds;
}
/// <summary>
/// Returns true if expand part space should be accounted for even if they expand part is not visible or need to be displayed. Default value is false.
/// </summary>
protected override bool ReserveExpandPartSpace
{
get
{
return true;
}
}
/// <summary>
/// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout.
/// </summary>
/// <param name="node">Node to get expand part alignment for</param>
/// <returns>true if node expand part is aligned to the left in left-to-right layout.</returns>
private bool ExpandPartAlignedNear(Node node)
{
return true; // If changed LayoutExpandPart needs to be updated as well
}
// private NodeCollection GetTopLevelNodes()
// {
// return m_Tree.Nodes;
// }
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,502 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents collection for Node objects.
/// </summary>
public class NodeCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
private AdvTree m_TreeControl=null;
private eTreeAction m_SourceAction=eTreeAction.Code;
private bool _PassiveCollection = false;
#endregion
#region Internal Implementation
public NodeCollection()
{
}
internal eTreeAction SourceAction
{
get
{
return m_SourceAction;
}
set
{
m_SourceAction = value;
}
}
internal bool PassiveCollection
{
get { return _PassiveCollection; }
set
{
_PassiveCollection = value;
}
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Node that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
internal AdvTree TreeControl
{
get {return m_TreeControl;}
set {m_TreeControl=value;}
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="node">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public virtual int Add(Node node)
{
return Add(node, eTreeAction.Code);
}
/// <summary>
/// Adds new object to the collection and provides information about the source of the command
/// </summary>
/// <param name="node">Node to add</param>
/// <param name="action">Source action</param>
/// <returns></returns>
public virtual int Add(Node node, eTreeAction action)
{
m_SourceAction = action;
return List.Add(node);
}
/// <summary>
/// Adds an array of objects to the collection.
/// </summary>
/// <param name="nodes">Array of Node objects.</param>
public virtual void AddRange(Node[] nodes)
{
foreach(Node node in nodes)
this.Add(node);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Node this[int index]
{
get {return (Node)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public virtual void Insert(int index, Node value)
{
List.Insert(index, value);
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
/// <param name="action">Action that is causing the event</param>
public virtual void Insert(int index, Node value, eTreeAction action)
{
m_SourceAction = action;
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Node value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Node value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public virtual void Remove(Node value)
{
List.Remove(value);
}
/// <summary>
/// Removes specified object from the collection and provides information about source of the command
/// </summary>
/// <param name="node">Node to remove</param>
/// <param name="action">Source action</param>
public virtual void Remove(Node node, eTreeAction action)
{
m_SourceAction = action;
List.Remove(node);
}
protected override void OnRemove(int index, object value)
{
if (!_PassiveCollection)
{
AdvTree tree = GetTreeControl();
if (tree != null)
tree.InvokeBeforeNodeRemove(m_SourceAction, value as Node, m_ParentNode);
}
base.OnRemove (index, value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
NodeRemoveComplete(index, value);
}
private void NodeRemoveComplete(int index, object value)
{
if (!_PassiveCollection)
{
Node node = value as Node;
node.SetParent(null);
node.internalTreeControl = null;
if (m_ParentNode != null) m_ParentNode.OnChildNodeRemoved(node);
AdvTree tree = GetTreeControl();
if (tree != null)
{
//tree.InvokeAfterNodeRemove(m_SourceAction, value as Node, m_ParentNode);
tree.NodeRemoved(m_SourceAction, value as Node, m_ParentNode, index);
}
}
}
protected override void OnSetComplete(int index, object oldValue, object newValue)
{
base.OnSetComplete(index, oldValue, newValue);
NodeRemoveComplete(index, oldValue);
NodeInsertComplete(newValue);
}
protected override void OnSet(int index, object oldValue, object newValue)
{
if (!_PassiveCollection)
{
AdvTree tree = GetTreeControl();
if (tree != null)
tree.InvokeBeforeNodeRemove(m_SourceAction, oldValue as Node, m_ParentNode);
if (tree != null)
tree.InvokeBeforeNodeInsert(m_SourceAction, newValue as Node, m_ParentNode);
}
base.OnSet(index, oldValue, newValue);
}
protected override void OnInsert(int index, object value)
{
if (!_PassiveCollection)
{
AdvTree tree = GetTreeControl();
if (tree != null)
tree.InvokeBeforeNodeInsert(m_SourceAction, value as Node, m_ParentNode);
}
base.OnInsert (index, value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
NodeInsertComplete(value);
}
private void NodeInsertComplete(object value)
{
if (!_PassiveCollection)
{
Node node = value as Node;
if (m_ParentNode != null)
{
if (node.Parent != null && node.Parent != m_ParentNode)
node.Remove();
node.SetParent(m_ParentNode);
if (m_ParentNode.NodesColumns.IsSorted)
{
AdvTree parentTree = m_TreeControl;
if (parentTree == null) parentTree = m_ParentNode.TreeControl;
if (parentTree != null)
parentTree.PushSortRequest(m_ParentNode);
}
}
else
{
if (node.Parent != null)
node.Remove();
else
node.InvokeOnParentChanged();
if (m_TreeControl != null && m_TreeControl.Columns.IsSorted)
{
m_TreeControl.PushSortRequest();
}
}
node.internalTreeControl = m_TreeControl;
if (m_ParentNode != null)
m_ParentNode.OnChildNodeInserted(node);
else
node.SizeChanged = true;
AdvTree tree = GetTreeControl();
if (tree != null)
tree.InvokeAfterNodeInsert(m_SourceAction, value as Node, m_ParentNode);
}
m_SourceAction = eTreeAction.Code;
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Node[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Node array.
/// </summary>
/// <param name="array">Array to copy to.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public void CopyTo(Node[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
if (!_PassiveCollection)
{
foreach (Node node in this.List)
{
node.SetParent(null);
node.internalTreeControl = null;
}
}
base.OnClear();
}
protected override void OnClearComplete()
{
if (m_TreeControl != null && !PassiveCollection)
{
m_TreeControl.OnNodesCleared();
}
else if (m_ParentNode != null && !PassiveCollection)
m_ParentNode.OnNodesCleared();
AdvTree tree = GetTreeControl();
if (tree != null)
{
tree.ValidateSelectedNode();
}
base.OnClearComplete();
}
private AdvTree GetTreeControl()
{
if(m_TreeControl!=null)
return m_TreeControl;
if(m_ParentNode!=null)
return m_ParentNode.TreeControl;
return null;
}
/// <summary>
/// Sorts the elements in the entire collection using the IComparable implementation of each element.
/// </summary>
public virtual void Sort()
{
this.Sort(0, this.Count, Comparer.Default);
}
/// <summary>
/// Sorts the elements in the entire collection using the specified comparer.
/// </summary>
/// <param name="comparer">The IComparer implementation to use when comparing elements.-or- null to use the IComparable implementation of each element.</param>
public virtual void Sort(IComparer comparer)
{
this.Sort(0, this.Count, comparer);
}
/// <summary>
/// Sorts the elements in a range of elements in collection using the specified comparer.
/// </summary>
/// <param name="index"></param>
/// <param name="count"></param>
/// <param name="comparer"></param>
public virtual void Sort(int index, int count, IComparer comparer)
{
AdvTree tree = GetTreeControl();
if (!_PassiveCollection && tree != null)
tree.BeginUpdate();
this.InnerList.Sort(index, count, comparer);
if (tree != null && tree.DeepSort)
{
foreach (Node node in this.InnerList)
{
node.Nodes.Sort(0, node.Nodes.Count, comparer);
}
}
if (!_PassiveCollection && tree != null)
tree.EndUpdate();
}
/// <summary>
/// Finds the tree nodes with specified key, optionally searching sub-nodes.
/// </summary>
/// <param name="name">The name of the tree node to search for.</param>
/// <param name="searchAllChildren">true to search child nodes of tree nodes; otherwise, false. </param>
/// <returns>An array of Node objects whose Name property matches the specified key.</returns>
public Node[] Find(string name, bool searchAllChildren)
{
ArrayList list = new ArrayList();
NodeOperations.FindNodesByName(this, name, searchAllChildren, list);
Node[] nodes = new Node[list.Count];
if (list.Count > 0) list.CopyTo(nodes);
return nodes;
}
#endregion
}
#region Node Comparer
public class NodeComparer : IComparer
{
private int _ColumnIndex = 0;
/// <summary>
/// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling
/// NodeCollection.Sort method and pass new instance of NodeComparer class.
/// </summary>
public NodeComparer()
{
}
/// <summary>
/// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling
/// NodeCollection.Sort method and pass new instance of NodeComparer class.
/// </summary>
/// <param name="columnIndex">Column/Cell index to use for sorting.</param>
public NodeComparer(int columnIndex)
{
_ColumnIndex = columnIndex;
}
/// <summary>
/// Gets or sets the Column/Cell index that is used for sorting.
/// </summary>
public int ColumnIndex
{
get { return _ColumnIndex; }
set { _ColumnIndex = value; }
}
#region IComparer Members
public virtual int Compare(object x, object y)
{
Node nx = (Node)x;
Node ny = (Node)y;
if (_ColumnIndex < nx.Cells.Count && _ColumnIndex < ny.Cells.Count)
{
if(AdvTreeSettings.UseSortAlphaComparer)
return Utilities.CompareAlpha(nx.Cells[_ColumnIndex].Text, ny.Cells[_ColumnIndex].Text);
else
return Utilities.CompareAlphaNumeric(nx.Cells[_ColumnIndex].Text, ny.Cells[_ColumnIndex].Text);
}
return 0;
}
#endregion
}
/// <summary>
/// Reverse sort nodes.
/// </summary>
public class NodeComparerReverse : NodeComparer
{
/// <summary>
/// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling
/// NodeCollection.Sort method and pass new instance of NodeComparer class.
/// </summary>
/// <param name="columnIndex">Column/Cell index to use for sorting.</param>
public NodeComparerReverse(int columnIndex) : base(columnIndex)
{
}
public override int Compare(object x, object y)
{
return base.Compare(y, x);
}
}
/// <summary>
/// Sort by flat node index.
/// </summary>
public class NodeFlatIndexComparer : IComparer
{
private AdvTree _TreeControl = null;
/// <summary>
/// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling
/// NodeCollection.Sort method and pass new instance of NodeComparer class.
/// </summary>
public NodeFlatIndexComparer(AdvTree treeControl)
{
_TreeControl = treeControl;
}
#region IComparer Members
public virtual int Compare(object x, object y)
{
Node nx = (Node)x;
Node ny = (Node)y;
if (_TreeControl.GetNodeFlatIndex(nx) < _TreeControl.GetNodeFlatIndex(ny))
return -1;
else
return 1;
}
#endregion
}
#endregion
}

View File

@ -0,0 +1,215 @@
using System;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents node connector. Node connector is the line that is drawn to indicate connection between child and parent node.
/// </summary>
[ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false),TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class NodeConnector:Component
{
#region Private Variables
private int m_LineWidth=1;
private Color m_LineColor=SystemColors.Highlight;
private eNodeConnectorType m_ConnectorType=eNodeConnectorType.Line;
//private bool m_UnderlineNoBorderNode=true;
//private eConnectorCap m_EndCap=eConnectorCap.Ellipse;
//private eConnectorCap m_StartCap=eConnectorCap.None;
//private Size m_EndCapSize=new Size(5,5);
//private Size m_StartCapSize=new Size(5,5);
#endregion
#region Events
/// <summary>
/// Occurs when appearance of the connector has changed as result of changed settings on the connector.
/// </summary>
public event EventHandler AppearanceChanged;
#endregion
#region Public Interface
/// <summary>
/// Default Constructor.
/// </summary>
public NodeConnector()
{
}
/// <summary>
/// Creates new instance of the object with specified parameters.
/// </summary>
/// <param name="lineWidth">Connector line width.</param>
/// <param name="type">Connector type.</param>
public NodeConnector(int lineWidth, eNodeConnectorType type)
{
this.LineWidth=lineWidth;
this.ConnectorType=type;
}
/// <summary>
/// Gets or sets the connector line width.
/// </summary>
[Browsable(true),DefaultValue(1),Category("Appearance"),Description("Indicates connector line width.")]
public int LineWidth
{
get {return m_LineWidth;}
set
{
m_LineWidth=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Gets or sets the color of the connector line.
/// </summary>
[Browsable(true),Category("Appearance"),Description("Indicates color of the connector line.")]
public Color LineColor
{
get {return m_LineColor;}
set
{
m_LineColor=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Returns true if editor should serialize LineColor property.
/// </summary>
[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeLineColor()
{
return m_LineColor!=SystemColors.Highlight;
}
/// <summary>
/// Gets or sets the type of the connector.
/// </summary>
/// <remarks>
/// See <see cref="eNodeConnectorType">eNodeConnectorType</see> enum for list of
/// available connectors.
/// </remarks>
/// <seealso cref="eNodeConnectorType">eNodeConnectorType Enumeration</seealso>
[Browsable(false),DefaultValue(eNodeConnectorType.Line),Category("Appearance"),Description("Indicates visual type of the connector.")]
public eNodeConnectorType ConnectorType
{
get {return m_ConnectorType;}
set
{
m_ConnectorType=value;
OnAppearanceChanged();
}
}
private DashStyle _DashStyle = DashStyle.Dot;
/// <summary>
/// Gets or sets the DashStyle for the connector line. Default value is DashStyle.Dot.
/// </summary>
[DefaultValue(DashStyle.Dot), Category("Appearance"), Description("Indicates DashStyle for the connector line")]
public DashStyle DashStyle
{
get { return _DashStyle; }
set { _DashStyle = value; }
}
///// <summary>
///// Gets or sets whether the child node without borders is underlined as a
///// continuation of the connector from node's parent. Default value is true.
///// </summary>
///// <remarks>
///// To enhance visual appearance of the connectors that are connecting to the node
///// with no borders assigned the connector is continued as a single line under the node
///// when this property is set to true (default) value.
///// </remarks>
//[Browsable(true), DefaultValue(true), Category("Behavior"), Description("Indicates whether connector is drawn under the nodes with no borders assigned.")]
//public bool UnderlineNoBorderNode
//{
// get { return m_UnderlineNoBorderNode; }
// set
// {
// m_UnderlineNoBorderNode = value;
// OnAppearanceChanged();
// }
//}
///// <summary>
///// Gets or sets the type of the cap that connector is ended with. Note that connector starts with parent node and ends with the child node. Default value is Ellipse.
///// </summary>
//[Browsable(true),DefaultValue(eConnectorCap.Ellipse),Category("Appearance"),Description("Indicates type of the cap that connector is ended with.")]
//public eConnectorCap EndCap
//{
// get {return m_EndCap;}
// set
// {
// m_EndCap=value;
// OnAppearanceChanged();
// }
//}
///// <summary>
///// Gets or sets the size of the end cap.
///// </summary>
//[Browsable(true),Category("Appearance"),Description("Indicates the size of the end cap.")]
//public System.Drawing.Size EndCapSize
//{
// get {return m_EndCapSize;}
// set
// {
// m_EndCapSize=value;
// OnAppearanceChanged();
// }
//}
///// <summary>
///// Returns true if EndCapSize property should be serialized by editor.
///// </summary>
///// <returns></returns>
//[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
//public bool ShouldSerializeEndCapSize()
//{
// return (m_EndCapSize.Width!=5 || m_EndCapSize.Height!=5);
//}
#endregion
#region Private Implementation
private void OnAppearanceChanged()
{
if(AppearanceChanged!=null)
AppearanceChanged(this,new EventArgs());
}
#endregion
// /// <summary>
// /// Gets or sets the type of the cap that connector is started with. Note that connector starts with parent node and ends with the child node. Default value is None.
// /// </summary>
// [Browsable(true),DefaultValue(eConnectorCap.None),Category("Appearance"),Description("Indicates type of the cap that connector is starts with.")]
// public eConnectorCap StartCap
// {
// get {return m_StartCap;}
// set {m_StartCap=value;}
// }
//
// /// <summary>
// /// Gets or sets the size of the start cap.
// /// </summary>
// [Browsable(true),Category("Appearance"),Description("Indicates the size of the start cap.")]
// public System.Drawing.Size StartCapSize
// {
// get {return m_StartCapSize;}
// set {m_StartCapSize=value;}
// }
//
// /// <summary>
// /// Returns true if StartCapSize property should be serialized by editor.
// /// </summary>
// /// <returns></returns>
// [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
// public bool ShouldSerializeStartCapSize()
// {
// return (m_StartCapSize.Width!=5 || m_StartCapSize.Height!=5);
// }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,463 @@
using System;
using System.ComponentModel;
using System.Drawing;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree
{
/// <summary>
/// Class that provides predefined styles for the nodes. Styles are defined as static memeber of the class
/// </summary>
public class NodeStyles
{
private static ElementStyle s_AppleStyle=null;
private static ElementStyle s_BlueStyle=null;
private static ElementStyle s_BlueLightStyle=null;
private static ElementStyle s_BlueNightStyle=null;
private static ElementStyle s_BlueMistStyle=null;
private static ElementStyle s_CyanStyle=null;
private static ElementStyle s_GreenStyle=null;
private static ElementStyle s_LemonStyle=null;
private static ElementStyle s_MagentaStyle=null;
private static ElementStyle s_OrangeStyle=null;
private static ElementStyle s_OrangeLightStyle=null;
private static ElementStyle s_PurpleStyle=null;
private static ElementStyle s_PurpleMistStyle=null;
private static ElementStyle s_RedStyle=null;
private static ElementStyle s_SilverStyle=null;
private static ElementStyle s_SilverMistStyle=null;
private static ElementStyle s_TanStyle=null;
private static ElementStyle s_TealStyle=null;
private static ElementStyle s_YellowStyle=null;
private static ElementStyle s_GrayStyle=null;
/// <summary>
/// Returns Apple element style
/// </summary>
public static ElementStyle Apple
{
get
{
if(s_AppleStyle==null)
s_AppleStyle = GetStyle(ePredefinedElementStyle.Apple);
return s_AppleStyle;
}
}
/// <summary>
/// Returns Blue element style
/// </summary>
public static ElementStyle Blue
{
get
{
if(s_BlueStyle==null)
s_BlueStyle= GetStyle(ePredefinedElementStyle.Blue);
return s_BlueStyle;
}
}
/// <summary>
/// Returns BlueLight element style
/// </summary>
public static ElementStyle BlueLight
{
get
{
if(s_BlueLightStyle==null)
s_BlueLightStyle= GetStyle(ePredefinedElementStyle.BlueLight);
return s_BlueLightStyle;
}
}
/// <summary>
/// Returns BlueNight element style
/// </summary>
public static ElementStyle BlueNight
{
get
{
if(s_BlueNightStyle==null)
s_BlueNightStyle= GetStyle(ePredefinedElementStyle.BlueNight);
return s_BlueNightStyle;
}
}
/// <summary>
/// Returns BlueMist element style
/// </summary>
public static ElementStyle BlueMist
{
get
{
if(s_BlueMistStyle==null)
s_BlueMistStyle= GetStyle(ePredefinedElementStyle.BlueMist);
return s_BlueMistStyle;
}
}
/// <summary>
/// Returns Cyan element style
/// </summary>
public static ElementStyle Cyan
{
get
{
if(s_CyanStyle==null)
s_CyanStyle= GetStyle(ePredefinedElementStyle.Cyan);
return s_CyanStyle;
}
}
/// <summary>
/// Returns Green element style
/// </summary>
public static ElementStyle Green
{
get
{
if(s_GreenStyle==null)
s_GreenStyle= GetStyle(ePredefinedElementStyle.Green);
return s_GreenStyle;
}
}
/// <summary>
/// Returns Lemon element style
/// </summary>
public static ElementStyle Lemon
{
get
{
if(s_LemonStyle==null)
s_LemonStyle= GetStyle(ePredefinedElementStyle.Lemon);
return s_LemonStyle;
}
}
/// <summary>
/// Returns Magenta element style
/// </summary>
public static ElementStyle Magenta
{
get
{
if(s_MagentaStyle==null)
s_MagentaStyle= GetStyle(ePredefinedElementStyle.Magenta);
return s_MagentaStyle;
}
}
/// <summary>
/// Returns Orange element style
/// </summary>
public static ElementStyle Orange
{
get
{
if(s_OrangeStyle==null)
s_OrangeStyle= GetStyle(ePredefinedElementStyle.Orange);
return s_OrangeStyle;
}
}
/// <summary>
/// Returns OrangeLight element style
/// </summary>
public static ElementStyle OrangeLight
{
get
{
if(s_OrangeLightStyle==null)
s_OrangeLightStyle= GetStyle(ePredefinedElementStyle.OrangeLight);
return s_OrangeLightStyle;
}
}
/// <summary>
/// Returns Purple element style
/// </summary>
public static ElementStyle Purple
{
get
{
if(s_PurpleStyle==null)
s_PurpleStyle= GetStyle(ePredefinedElementStyle.Purple);
return s_PurpleStyle;
}
}
/// <summary>
/// Returns PurpleMist element style
/// </summary>
public static ElementStyle PurpleMist
{
get
{
if(s_PurpleMistStyle==null)
s_PurpleMistStyle= GetStyle(ePredefinedElementStyle.PurpleMist);
return s_PurpleMistStyle;
}
}
/// <summary>
/// Returns Red element style
/// </summary>
public static ElementStyle Red
{
get
{
if(s_RedStyle==null)
s_RedStyle= GetStyle(ePredefinedElementStyle.Red);
return s_RedStyle;
}
}
/// <summary>
/// Returns Silver element style
/// </summary>
public static ElementStyle Silver
{
get
{
if(s_SilverStyle==null)
s_SilverStyle= GetStyle(ePredefinedElementStyle.Silver);
return s_SilverStyle;
}
}
/// <summary>
/// Returns SilverMist element style
/// </summary>
public static ElementStyle SilverMist
{
get
{
if(s_SilverMistStyle==null)
s_SilverMistStyle= GetStyle(ePredefinedElementStyle.SilverMist);
return s_SilverMistStyle;
}
}
/// <summary>
/// Returns Tan element style
/// </summary>
public static ElementStyle Tan
{
get
{
if(s_TanStyle==null)
s_TanStyle= GetStyle(ePredefinedElementStyle.Tan);
return s_TanStyle;
}
}
/// <summary>
/// Returns Teal element style
/// </summary>
public static ElementStyle Teal
{
get
{
if(s_TealStyle==null)
s_TealStyle= GetStyle(ePredefinedElementStyle.Teal);
return s_TealStyle;
}
}
/// <summary>
/// Returns Yellow element style
/// </summary>
public static ElementStyle Yellow
{
get
{
if(s_YellowStyle==null)
s_YellowStyle= GetStyle(ePredefinedElementStyle.Yellow);
return s_YellowStyle;
}
}
/// <summary>
/// Returns Gray element style
/// </summary>
public static ElementStyle Gray
{
get
{
if(s_GrayStyle==null)
s_GrayStyle= GetStyle(ePredefinedElementStyle.Gray);
return s_GrayStyle;
}
}
private static ElementStyle GetStyle(ePredefinedElementStyle c)
{
Color color1=Color.Empty;
Color color2=Color.Empty;
int gradientAngle = 90;
Color textColor=Color.Black;
Color borderColor = Color.DarkGray;
switch (c)
{
case ePredefinedElementStyle.Apple:
{
color1 = Color.FromArgb(232, 248, 224);
color2 = Color.FromArgb(173, 231, 146);
break;
}
case ePredefinedElementStyle.Blue:
{
color1 = Color.FromArgb(221, 230, 247);
color2 = Color.FromArgb(138, 168, 228);
break;
}
case ePredefinedElementStyle.BlueLight:
{
color1=Color.FromArgb(255,255,255);
color2=Color.FromArgb(210,224,252);
textColor=Color.FromArgb(69,84,115);
break;
}
case ePredefinedElementStyle.BlueMist:
{
color1 = Color.FromArgb(227, 236, 243);
color2 = Color.FromArgb(155, 187, 210);
break;
}
case ePredefinedElementStyle.BlueNight:
{
color1=Color.FromArgb(77,108,152);
color2=Color.Navy;
textColor=Color.White;
borderColor=Color.Navy;
break;
}
case ePredefinedElementStyle.Cyan:
{
color1 = Color.FromArgb(227, 236, 243);
color2 = Color.FromArgb(155, 187, 210);
break;
}
case ePredefinedElementStyle.Green:
{
color1 = Color.FromArgb(234, 240, 226);
color2 = Color.FromArgb(183, 201, 151);
break;
}
case ePredefinedElementStyle.Lemon:
{
color1 = Color.FromArgb(252, 253, 215);
color2 = Color.FromArgb(245, 249, 111);
break;
}
case ePredefinedElementStyle.Magenta:
{
color1 = Color.FromArgb(243, 229, 236);
color2 = Color.FromArgb(213, 164, 187);
break;
}
case ePredefinedElementStyle.Orange:
{
color1 = Color.FromArgb(252, 233, 217);
color2 = Color.FromArgb(246, 176, 120);
break;
}
case ePredefinedElementStyle.OrangeLight:
{
color1=Color.FromArgb(255,239,201);
color2=Color.FromArgb(242,210,132);
textColor=Color.FromArgb(117,83,2);
break;
}
case ePredefinedElementStyle.Purple:
{
color1 = Color.FromArgb(234, 227, 245);
color2 = Color.FromArgb(180, 158, 222);
break;
}
case ePredefinedElementStyle.PurpleMist:
{
color1 = Color.FromArgb(232, 227, 234);
color2 = Color.FromArgb(171, 156, 183);
break;
}
case ePredefinedElementStyle.Red:
{
color1 = Color.FromArgb(249, 225, 226);
color2 = Color.FromArgb(238, 149, 151);
break;
}
case ePredefinedElementStyle.Silver:
{
color1 = Color.FromArgb(225, 225, 232);
color2 = Color.FromArgb(149, 149, 170);
break;
}
case ePredefinedElementStyle.SilverMist:
{
color1 = Color.FromArgb(243,244,250);
color2=Color.FromArgb(155,153,183);
textColor=Color.FromArgb(87,86,113);
break;
}
case ePredefinedElementStyle.Tan:
{
color1 = Color.FromArgb(248, 242, 226);
color2 = Color.FromArgb(232, 209, 153);
break;
}
case ePredefinedElementStyle.Teal:
{
color1 = Color.FromArgb(205, 236, 240);
color2 = Color.FromArgb(78, 188, 202);
break;
}
case ePredefinedElementStyle.Yellow:
{
color1 = Color.FromArgb(255, 244, 213);
color2 = Color.FromArgb(255, 216, 105);
break;
}
case ePredefinedElementStyle.Gray:
{
color1 = Color.White;
color2 = ColorScheme.GetColor("E4E4F0");
break;
}
}
ElementStyle style=Utilities.CreateStyle(new ComponentFactory(),Enum.GetName(typeof(ePredefinedElementStyle),c),borderColor,color1, color2, gradientAngle,textColor);
return style;
}
}
/// <summary>
/// Indicates predefined element style.
/// </summary>
public enum ePredefinedElementStyle
{
Blue,
BlueLight,
BlueNight,
Yellow,
Green,
Red,
Purple,
Cyan,
Orange,
OrangeLight,
Magenta,
BlueMist,
PurpleMist,
Tan,
Lemon,
Apple,
Teal,
Silver,
SilverMist,
Gray
}
}

View File

@ -0,0 +1,160 @@
using System;
using System.Text;
using System.Collections.Generic;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents the selected nodes collection.
/// </summary>
public class SelectedNodesCollection : NodeCollection
{
#region Internal Implementation
internal AdvTree TreeSelectionControl = null;
internal bool SuspendEvents = false;
internal bool SuspendClearEvents = false;
/// <summary>
/// Initializes a new instance of the SelectedNodesCollection class.
/// </summary>
public SelectedNodesCollection()
{
PassiveCollection = true;
}
/// <summary>
/// Adds new object to the collection and provides information about the source of the command
/// </summary>
/// <param name="node">Node to add</param>
/// <param name="action">Source action</param>
/// <returns></returns>
public override int Add(Node node, eTreeAction action)
{
if (this.List.Contains(node)) return -1;
if (TreeSelectionControl.MultiSelect)
{
if (TreeSelectionControl.MultiSelectRule == eMultiSelectRule.SameParent && this.Count>0)
{
if (this[0].Parent != node.Parent)
throw new InvalidOperationException("Node being added does not belong to the same parent as currently selected nodes. See AdvTree.MultiSelectRule property");
}
if (!SuspendEvents)
{
AdvTreeNodeCancelEventArgs cancelArgs = new AdvTreeNodeCancelEventArgs(action, node);
TreeSelectionControl.InvokeOnBeforeNodeSelect(cancelArgs);
if (cancelArgs.Cancel)
return -1;
}
}
return base.Add(node, action);
}
/// <summary>
/// Adds an array of objects to the collection.
/// </summary>
/// <param name="nodes">Array of Node objects.</param>
public override void AddRange(Node[] nodes)
{
this.MultiNodeOperation = true;
base.AddRange(nodes);
this.MultiNodeOperation = false;
if (!SuspendEvents)
TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty);
}
protected override void OnInsertComplete(int index, object value)
{
if (TreeSelectionControl.MultiSelect)
{
Node node = value as Node;
node.IsSelected = true;
TreeSelectionControl.InvalidateNode(node);
if (node.SelectedCell == null)
{
node.SelectFirstCell(SourceAction);
}
AdvTreeNodeEventArgs args = new AdvTreeNodeEventArgs(SourceAction, node);
TreeSelectionControl.InvokeOnAfterNodeSelect(args);
node.InternalSelected(this.SourceAction);
if(!_MultiNodeOperation)
TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty);
}
base.OnInsertComplete(index, value);
}
protected override void OnRemoveComplete(int index, object value)
{
if (TreeSelectionControl.MultiSelect)
{
Node node = value as Node;
node.IsSelected = false;
TreeSelectionControl.InvalidateNode(node);
if (node.SelectedCell != null)
node.SelectedCell.SetSelected(false, SourceAction);
TreeSelectionControl.InvokeOnAfterNodeDeselect(new AdvTreeNodeEventArgs(this.SourceAction, node));
node.InternalDeselected(this.SourceAction);
if (!_MultiNodeOperation)
TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty);
}
base.OnRemoveComplete(index, value);
}
private int _NumberOfClearedNodes = 0;
protected override void OnClear()
{
if (TreeSelectionControl.MultiSelect)
{
_NumberOfClearedNodes = this.List.Count;
Node[] list = new Node[_NumberOfClearedNodes];
this.List.CopyTo(list, 0);
foreach (Node node in list)
{
node.IsSelected = false;
TreeSelectionControl.InvalidateNode(node);
if (node.SelectedCell == null)
node.Cells[0].SetSelected(false, SourceAction);
_ClearedEventArgsList.Add(new AdvTreeNodeEventArgs(this.SourceAction, node)); // Delay event notification to OnClearComplete so node is not in collection if collection is being tested
//TreeSelectionControl.InvokeOnAfterNodeDeselect(new AdvTreeNodeEventArgs(this.SourceAction, node));
node.InternalDeselected(this.SourceAction);
}
}
base.OnClear();
}
private List<AdvTreeNodeEventArgs> _ClearedEventArgsList = new List<AdvTreeNodeEventArgs>();
protected override void OnClearComplete()
{
if (TreeSelectionControl.MultiSelect)
{
if (TreeSelectionControl != null && !SuspendClearEvents)
{
// Invoke nodes deselected
foreach (AdvTreeNodeEventArgs advTreeNodeEventArgs in _ClearedEventArgsList)
{
TreeSelectionControl.InvokeOnAfterNodeDeselect(advTreeNodeEventArgs);
}
}
_ClearedEventArgsList.Clear();
if (!SuspendClearEvents && _NumberOfClearedNodes > 0)
TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty);
}
base.OnClearComplete();
}
private bool _MultiNodeOperation;
internal bool MultiNodeOperation
{
get
{
return _MultiNodeOperation;
}
set
{
_MultiNodeOperation = value;
}
}
#endregion
}
}

View File

@ -0,0 +1,159 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents the text box for editing cell's text.
/// </summary>
[Designer("System.Windows.Forms.Design.ControlDesigner, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),ToolboxItem(false)]
internal class TextBoxEx:TextBox, ICellEditControl
{
#region Private variables
private bool m_WordWrap=false;
#endregion
#region Events
public event EventHandler EditComplete;
public event EventHandler CancelEdit;
#endregion
#region Constructor
public TextBoxEx():base()
{
this.AutoSize=false;
this.BorderStyle=System.Windows.Forms.BorderStyle.None;
}
#endregion
#region Internal Implementation
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if(e.KeyCode==Keys.Enter && !m_WordWrap || e.KeyCode==Keys.Enter && e.Modifiers==Keys.Control)
{
if(EditComplete!=null)
EditComplete(this, new EventArgs());
}
else if(e.KeyCode==Keys.Escape)
{
if(CancelEdit!=null)
CancelEdit(this,new EventArgs());
}
}
#if FRAMEWORK20
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (!m_WordWrap && _PreventEnterBeep && e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
}
base.OnKeyPress(e);
}
#endif
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab)
{
if (EditComplete != null)
EditComplete(this, new EventArgs());
}
return base.ProcessCmdKey(ref msg, keyData);
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged (e);
ResizeControl();
}
private void ResizeControl()
{
Graphics g=this.CreateGraphics();
SizeF size=g.MeasureString(this.Text,this.Font);
int width=(int)Math.Ceiling(size.Width);
int height=(int)Math.Ceiling(size.Height);
if (this.Parent != null && this.Right + (width - this.Width) > (this.Parent.ClientRectangle.Right - SystemInformation.VerticalScrollBarWidth - 2))
return;
if (width > this.Width)
this.Width = width;
if(m_WordWrap)
{
if(this.Parent!=null && this.Bottom+(height-this.Height)>this.Parent.Bottom)
return;
if(height>this.Height)
this.Height=height;
}
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets whether the editing is in word-wrap mode.
/// </summary>
public bool EditWordWrap
{
get {return m_WordWrap;}
set
{
m_WordWrap=value;
if(m_WordWrap)
{
this.Multiline=true;
this.ScrollBars=ScrollBars.None;
}
else
{
this.Multiline=false;
}
}
}
private bool _PreventEnterBeep = false;
/// <summary>
/// Gets or sets whether control prevents Beep sound when Enter key is pressed.
/// </summary>
[DefaultValue(false), Category("Behavior"), Description("Gets or sets whether control prevents Beep sound when Enter key is pressed.")]
public bool PreventEnterBeep
{
get { return _PreventEnterBeep; }
set
{
_PreventEnterBeep = value;
}
}
#endregion
#region ICellEditControl Members
public void BeginEdit()
{
}
public void EndEdit()
{
}
public object CurrentValue
{
get
{
return this.Text;
}
set
{
this.Text = value.ToString();
}
}
#endregion
}
}

View File

@ -0,0 +1,60 @@
namespace DevComponents.AdvTree
{
/// <summary>
/// Summary description for TreeAreaInfo.
/// </summary>
internal class TreeAreaInfo
{
/// <summary>
/// Reference to parent node in which child bounds the coordinates are. Can be null if no parent node contains given coordinates.
/// </summary>
public Node ParentAreaNode=null;
/// <summary>
/// Node which contains specified coordinates. Can be null if no node contains coordinates.
/// </summary>
public Node NodeAt=null;
/// <summary>
/// Previous reference node for given coordinates. If coordinates fall between two nodes this will indicate previous node or null.
/// </summary>
public Node PreviousNode=null;
/// <summary>
/// Next reference node for given coordinates. If coordinates fall between two nodes this will indicate next node or null.
/// </summary>
public Node NextNode=null;
}
internal class NodeDragInfo
{
/// <summary>
/// Gets or sets the parent node drag node will be added to. When null the drag node is being added as top-level node.
/// </summary>
public Node Parent = null;
/// <summary>
/// Gets or sets the insert index of drag node into the parent's node Nodes collection.
/// </summary>
public int InsertIndex = -1;
/// <summary>
/// Initializes a new instance of the NodeDragInfo class.
/// </summary>
public NodeDragInfo()
{
}
/// <summary>
/// Initializes a new instance of the NodeDragInfo class.
/// </summary>
/// <param name="parent"></param>
/// <param name="insertIndex"></param>
public NodeDragInfo(Node parent, int insertIndex)
{
Parent = parent;
InsertIndex = insertIndex;
}
public override string ToString()
{
return string.Format("NodeDragInfo-> Parent={0}, InsertIndex={1}", Parent, InsertIndex);
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Windows.Forms;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides data for AdvTree Cell events that can be canceled.
/// </summary>
public class TreeCellCancelEventArgs:AdvTreeCellEventArgs
{
/// <summary>
/// Default constructor for event data.
/// </summary>
/// <param name="action">Type of the action event is raised for.</param>
/// <param name="cell">Cell that event is raised for.</param>
public TreeCellCancelEventArgs(eTreeAction action, Cell cell):base(action,cell)
{
}
/// <summary>
/// Indicates that event action should be canceled.
/// </summary>
public bool Cancel=false;
}
/// <summary>
/// Provides data for AdvTree.BeforeCheck event.
/// </summary>
public class AdvTreeCellBeforeCheckEventArgs : TreeCellCancelEventArgs
{
public CheckState NewCheckState = CheckState.Indeterminate;
/// <summary>
/// Initializes a new instance of the AdvTreeCellBeforeCheckEventArgs class.
/// </summary>
/// <param name="newCheckState"></param>
public AdvTreeCellBeforeCheckEventArgs(eTreeAction action, Cell cell, CheckState newCheckState)
: base(action, cell)
{
NewCheckState = newCheckState;
}
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides data for AdvTree Cell events.
/// </summary>
public class AdvTreeCellEventArgs:EventArgs
{
/// <summary>
/// Default constructor for event data.
/// </summary>
/// <param name="action">Type of the action event is raised for.</param>
/// <param name="cell">Cell that event is raised for.</param>
public AdvTreeCellEventArgs(eTreeAction action, Cell cell)
{
this.Action=action;
this.Cell=cell;
}
/// <summary>
/// Indicates the type of the action performed on a cell.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the cell that action is performed on.
/// </summary>
public DevComponents.AdvTree.Cell Cell=null;
}
}

View File

@ -0,0 +1,48 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents event arguments for BeforeNodeDrop and AfterNodeDrop events
/// </summary>
public class TreeDragDropEventArgs : AdvTreeMultiNodeCancelEventArgs
{
public TreeDragDropEventArgs(eTreeAction action, Node[] nodes, Node oldParentNode, Node newParentNode, int insertPosition)
: base(action, nodes)
{
this.NewParentNode = newParentNode;
this.OldParentNode = oldParentNode;
this.InsertPosition = insertPosition;
}
public TreeDragDropEventArgs(eTreeAction action, Node[] nodes, Node oldParentNode, Node newParentNode, bool isCopy, int insertPosition)
: base(action, nodes)
{
this.NewParentNode = newParentNode;
this.OldParentNode = oldParentNode;
this.IsCopy = isCopy;
this.InsertPosition = insertPosition;
}
/// <summary>
/// Returns reference to the old parent node.
/// </summary>
public readonly Node OldParentNode=null;
/// <summary>
/// Reference to the new parent node if event is not cancelled.
/// </summary>
public readonly Node NewParentNode=null;
/// <summary>
/// Gets or sets whether drag node is being copied instead of moved.
/// </summary>
public bool IsCopy = false;
/// <summary>
/// Gets or sets the new insert position inside of NewParentNode.Nodes collection for the node being dragged. If InsertPosition is -1
/// the ParentNode refers to the current mouse over node and drag &amp; drop node will be added as child node to it.
/// </summary>
public int InsertPosition = 0;
}
}

View File

@ -0,0 +1,129 @@
using System;
using System.Text;
using System.Windows.Forms;
namespace DevComponents.AdvTree
{
/// <summary>
/// Defines the data for NodeDragFeedback event.
/// </summary>
public class TreeDragFeedbackEventArgs : EventArgs
{
/// <summary>
/// Gets or sets whether this drop location is accepted. Default value is true. You can set this to false to disable drop at this location.
/// </summary>
public bool AllowDrop = true;
/// <summary>
/// Gets or sets the parent node for the node that is being dragged. This can be null/nothing value to indicate a root top-level node that
/// is in AdvTree.Nodes collection.
/// </summary>
public Node ParentNode = null;
/// <summary>
/// Gets or sets the new insert position inside of ParentNode.Nodes collection for the node being dragged. If InsertPosition is -1
/// the ParentNode refers to the current mouse over node and drag &amp; drop node will be added as child node to it.
/// </summary>
public int InsertPosition = 0;
private Node _DragNode;
/// <summary>
/// Gets reference to the node being dragged.
/// </summary>
public Node DragNode
{
get { return _DragNode; }
#if FRAMEWORK20
set
{
_DragNode = value;
}
#endif
}
/// <summary>
/// Initializes a new instance of the TreeDragFeedbackEventArgs class.
/// </summary>
/// <param name="parentNode"></param>
/// <param name="insertPosition"></param>
public TreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node dragNode)
{
ParentNode = parentNode;
InsertPosition = insertPosition;
_DragNode = dragNode;
}
/// <summary>
/// Initializes a new instance of the TreeDragFeedbackEventArgs class.
/// </summary>
/// <param name="parentNode"></param>
/// <param name="insertPosition"></param>
public TreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node dragNode, DragDropEffects effect)
{
ParentNode = parentNode;
InsertPosition = insertPosition;
_DragNode = dragNode;
_Effect = effect;
}
/// <summary>
/// Initializes a new instance of the TreeDragFeedbackEventArgs class.
/// </summary>
public TreeDragFeedbackEventArgs()
{
}
internal bool EffectSet = false;
private DragDropEffects _Effect = DragDropEffects.None;
/// <summary>
/// Gets or sets the drop effect for the drag-drop operation.
/// </summary>
public DragDropEffects Effect
{
get { return _Effect; }
set
{
_Effect = value;
EffectSet = true;
}
}
}
public class MultiNodeTreeDragFeedbackEventArgs : TreeDragFeedbackEventArgs
{
/// <summary>
/// Initializes a new instance of the TreeDragFeedbackEventArgs class.
/// </summary>
/// <param name="parentNode"></param>
/// <param name="insertPosition"></param>
public MultiNodeTreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node[] dragNodes) :
base(parentNode, insertPosition, dragNodes[0])
{
_DragNodes = dragNodes;
}
/// <summary>
/// Initializes a new instance of the TreeDragFeedbackEventArgs class.
/// </summary>
/// <param name="parentNode"></param>
/// <param name="insertPosition"></param>
public MultiNodeTreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node[] dragNodes, DragDropEffects effect) :
base(parentNode, insertPosition, dragNodes[0], effect)
{
_DragNodes = dragNodes;
}
private Node[] _DragNodes;
/// <summary>
/// Gets reference to the node being dragged.
/// </summary>
public Node[] DragNodes
{
get { return _DragNodes; }
#if FRAMEWORK20
set
{
_DragNodes = value;
}
#endif
}
}
}

View File

@ -0,0 +1,46 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides data for AdvTree Node events that can be cancelled.
/// </summary>
public class AdvTreeNodeCancelEventArgs:AdvTreeNodeEventArgs
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="action">Default action</param>
/// <param name="node">Default node.</param>
public AdvTreeNodeCancelEventArgs(eTreeAction action, Node node):base(action,node)
{
}
/// <summary>
/// Indicates that event action should be canceled.
/// </summary>
public bool Cancel=false;
}
/// <summary>
/// Provides data for AdvTree Node events that can be cancelled.
/// </summary>
public class AdvTreeMultiNodeCancelEventArgs : AdvTreeNodeCancelEventArgs
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="action">Default action</param>
/// <param name="node">Default node.</param>
public AdvTreeMultiNodeCancelEventArgs(eTreeAction action, Node[] nodes)
: base(action, nodes[0])
{
Nodes = nodes;
}
/// <summary>
/// Indicates the array of nodes that action is performed on.
/// </summary>
public DevComponents.AdvTree.Node[] Nodes = null;
}
}

View File

@ -0,0 +1,28 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents event arguments for NodeCollection based events, like BeforeNodeInsert, AfterNodeInsert etc.
/// </summary>
public class TreeNodeCollectionEventArgs : AdvTreeNodeEventArgs
{
/// <summary>
/// Creates new instance of the class.
/// </summary>
/// <param name="action">Source action</param>
/// <param name="node">Affected node</param>
/// <param name="parentNode">Parent of the node if any</param>
public TreeNodeCollectionEventArgs(eTreeAction action, Node node, Node parentNode):base(action, node)
{
this.ParentNode = parentNode;
}
/// <summary>
/// Indicates parent node of the affected node. For example if event handled is BeforeNodeInsert parent of the Node is has
/// not been set yet so this property provides information on the node that will become parent. If this property returns null
/// then node is being added or removed from the main AdvTree.Nodes collection.
/// </summary>
public DevComponents.AdvTree.Node ParentNode=null;
}
}

View File

@ -0,0 +1,31 @@
using System;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides data for AdvTree Node events.
/// </summary>
public class AdvTreeNodeEventArgs:EventArgs
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="action">Default action</param>
/// <param name="node">Default node.</param>
public AdvTreeNodeEventArgs(eTreeAction action, Node node)
{
this.Action = action;
this.Node = node;
}
/// <summary>
/// Indicates the type of the action performed on a node.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the node that action is performed on.
/// </summary>
public DevComponents.AdvTree.Node Node=null;
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Windows.Forms;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents event arguments for node mouse based events.
/// </summary>
public class TreeNodeMouseEventArgs:EventArgs
{
public TreeNodeMouseEventArgs(Node node, MouseButtons button, int clicks, int delta, int x, int y)
{
this.Node = node;
this.Button = button;
this.Clicks = clicks;
this.Delta = delta;
this.X = x;
this.Y = y;
}
/// <summary>
/// Gets node affected by mouse action.
/// </summary>
public readonly Node Node;
/// <summary>
/// Gets which mouse button was pressed.
/// </summary>
public readonly MouseButtons Button;
/// <summary>
/// Gets the number of times the mouse button was pressed and released.
/// </summary>
public readonly int Clicks;
/// <summary>
/// Gets a signed count of the number of detents the mouse wheel has rotated. A detent is one notch of the mouse wheel.
/// </summary>
public readonly int Delta;
/// <summary>
/// Gets the x-coordinate of the mouse.
/// </summary>
public readonly int X;
/// <summary>
/// Gets the y-coordinate of the mouse.
/// </summary>
public readonly int Y;
}
}

View File

@ -0,0 +1,351 @@
using System;
using System.Xml;
using System.IO;
using DevComponents.DotNetBar;
namespace DevComponents.AdvTree
{
/// <summary>
/// Provides means for AdvTree serialization.
/// </summary>
public class TreeSerializer
{
#region Private Variables
private static string XmlNodeName="Node";
private static string XmlCellsName="Cells";
private static string XmlCellName="Cell";
private static string XmlCellImagesName="Images";
private static string XmlAdvTreeName="AdvTree";
private static string XmlCustomName = "Custom";
#endregion
#region Saving
/// <summary>
/// Saves Nodes to specified file.
/// </summary>
/// <param name="tree">AdvTree to save</param>
/// <param name="fileName">Target file name</param>
public static void Save(AdvTree tree, string fileName)
{
XmlDocument document=Save(tree);
document.Save(fileName);
}
/// <summary>
/// Saves Nodes to stream.
/// </summary>
/// <param name="tree">AdvTree to save</param>
/// <param name="outStream">Stream to save nodes to.</param>
public static void Save(AdvTree tree, Stream outStream)
{
XmlDocument document=Save(tree);
document.Save(outStream);
}
/// <summary>
/// Saves Nodes to TextWriter
/// </summary>
/// <param name="tree">AdvTree to save</param>
/// <param name="writer">TextWriter to write nodes to.</param>
public static void Save(AdvTree tree, TextWriter writer)
{
XmlDocument document=Save(tree);
document.Save(writer);
}
/// <summary>
/// Saves nodes to XmlWriter.
/// </summary>
/// <param name="tree">AdvTree to save</param>
/// <param name="writer">XmlWriter to write nodes to</param>
public static void Save(AdvTree tree, XmlWriter writer)
{
XmlDocument document=Save(tree);
document.Save(writer);
}
/// <summary>
/// Creates new XmlDocument and serializes AdvTree into it.
/// </summary>
/// <param name="tree">AdvTree to serialize</param>
/// <returns>New instance of XmlDocument/returns>
public static XmlDocument Save(AdvTree tree)
{
XmlDocument document=new XmlDocument();
Save(tree, document);
return document;
}
/// <summary>
/// Saves AdvTree to an existing XmlDocument. New node AdvTree is created in document and Nodes are serialized into it.
/// </summary>
/// <param name="tree">AdvTree to serialize</param>
/// <param name="document">XmlDocument instance.</param>
public static void Save(AdvTree tree, XmlDocument document)
{
XmlElement parent = document.CreateElement(XmlAdvTreeName);
document.AppendChild(parent);
TreeSerializer.Save(tree, parent);
}
/// <summary>
/// Serializes AdvTree object to XmlElement object.
/// </summary>
/// <param name="tree">Instance of AdvTree to serialize.</param>
/// <param name="parent">XmlElement to serialize to.</param>
public static void Save(AdvTree tree, XmlElement parent)
{
NodeSerializationContext context = new NodeSerializationContext();
context.RefXmlElement = parent;
context.AdvTree = tree;
context.HasSerializeNodeHandlers = tree.HasSerializeNodeHandlers;
context.HasDeserializeNodeHandlers = tree.HasDeserializeNodeHandlers;
foreach(Node node in tree.Nodes)
{
Save(node, context);
}
}
/// <summary>
/// Serializes Node and all child nodes to XmlElement object.
/// </summary>
/// <param name="node">Node to serialize.</param>
/// <param name="context">Provides serialization context.</param>
public static void Save(Node node, NodeSerializationContext context)
{
XmlElement parent = context.RefXmlElement;
XmlElement xmlNode=parent.OwnerDocument.CreateElement(XmlNodeName);
parent.AppendChild(xmlNode);
ElementSerializer.Serialize(node, xmlNode);
if(context.HasSerializeNodeHandlers)
{
XmlElement customXml = parent.OwnerDocument.CreateElement(XmlCustomName);
SerializeNodeEventArgs e = new SerializeNodeEventArgs(node, xmlNode, customXml);
context.AdvTree.InvokeSerializeNode(e);
if (customXml.Attributes.Count > 0 || customXml.ChildNodes.Count > 0)
xmlNode.AppendChild(customXml);
}
if(node.Cells.Count>1)
{
XmlElement xmlCells = parent.OwnerDocument.CreateElement(XmlCellsName);
xmlNode.AppendChild(xmlCells);
for(int i=1; i<node.Cells.Count;i++)
{
Cell cell=node.Cells[i];
XmlElement xmlCell= parent.OwnerDocument.CreateElement(XmlCellName);
xmlCells.AppendChild(xmlCell);
ElementSerializer.Serialize(cell, xmlCell);
if(cell.ShouldSerializeImages())
{
XmlElement xmlCellImages = parent.OwnerDocument.CreateElement(XmlCellImagesName);
xmlCell.AppendChild(xmlCellImages);
ElementSerializer.Serialize(cell.Images, xmlCellImages);
}
}
}
context.RefXmlElement = xmlNode;
foreach(Node childNode in node.Nodes)
{
Save(childNode, context);
}
context.RefXmlElement = parent;
}
#endregion
#region Loading
/// <summary>
/// Load AdvTree Nodes from file.
/// </summary>
/// <param name="tree">Reference to AdvTree to populate</param>
/// <param name="fileName">File name.</param>
public static void Load(AdvTree tree, string fileName)
{
XmlDocument document=new XmlDocument();
document.Load(fileName);
Load(tree, document);
}
/// <summary>
/// Load AdvTree Nodes from stream.
/// </summary>
/// <param name="tree">Reference to AdvTree to populate</param>
/// <param name="inStream">Reference to stream</param>
public static void Load(AdvTree tree, Stream inStream)
{
XmlDocument document=new XmlDocument();
document.Load(inStream);
Load(tree, document);
}
/// <summary>
/// Load AdvTree Nodes from reader.
/// </summary>
/// <param name="tree">Reference to AdvTree to populate</param>
/// <param name="reader">Reference to reader.</param>
public static void Load(AdvTree tree, TextReader reader)
{
XmlDocument document=new XmlDocument();
document.Load(reader);
Load(tree, document);
}
/// <summary>
/// Load AdvTree Nodes from reader.
/// </summary>
/// <param name="tree">Reference to AdvTree to populate</param>
/// <param name="reader">Reference to reader.</param>
public static void Load(AdvTree tree, XmlReader reader)
{
XmlDocument document=new XmlDocument();
document.Load(reader);
Load(tree, document);
}
/// <summary>
/// Load AdvTree from XmlDocument that was created by Save method.
/// </summary>
/// <param name="tree">Tree Control to load</param>
/// <param name="document">XmlDocument to load control from</param>
public static void Load(AdvTree tree, XmlDocument document)
{
foreach(XmlNode xmlNode in document.ChildNodes)
{
if(xmlNode.Name==XmlAdvTreeName && xmlNode is XmlElement)
{
Load(tree, xmlNode as XmlElement);
break;
}
}
}
/// <summary>
/// Load nodes from XmlElement.
/// </summary>
/// <param name="tree">Reference to AdvTree to be populated.</param>
/// <param name="parent">XmlElement that tree was serialized to.</param>
public static void Load(AdvTree tree, XmlElement parent)
{
tree.BeginUpdate();
tree.DisplayRootNode = null;
tree.Nodes.Clear();
NodeSerializationContext context = new NodeSerializationContext();
context.AdvTree = tree;
context.HasDeserializeNodeHandlers = tree.HasDeserializeNodeHandlers;
context.HasSerializeNodeHandlers = tree.HasSerializeNodeHandlers;
try
{
foreach(XmlNode xmlNode in parent.ChildNodes)
{
if(xmlNode.Name==XmlNodeName && xmlNode is XmlElement)
{
Node node=new Node();
tree.Nodes.Add(node);
context.RefXmlElement = xmlNode as XmlElement;
LoadNode(node, context);
}
}
}
finally
{
tree.EndUpdate();
}
}
/// <summary>
/// Load single node and it's child nodes if any.
/// </summary>
/// <param name="nodeToLoad">New instance of node that is populated with loaded data.</param>
/// <param name="context">Provides deserialization context.</param>
public static void LoadNode(Node nodeToLoad, NodeSerializationContext context)
{
XmlElement xmlNode = context.RefXmlElement;
ElementSerializer.Deserialize(nodeToLoad, xmlNode);
foreach(XmlNode xmlChild in xmlNode.ChildNodes)
{
XmlElement xmlElem = xmlChild as XmlElement;
if(xmlElem == null)
continue;
if(xmlElem.Name==XmlNodeName)
{
Node node=new Node();
nodeToLoad.Nodes.Add(node);
context.RefXmlElement = xmlElem;
LoadNode(node, context);
}
else if(xmlElem.Name == XmlCellsName)
{
LoadCells(nodeToLoad, xmlElem);
}
else if(xmlElem.Name == XmlCustomName)
{
if(context.HasDeserializeNodeHandlers)
{
SerializeNodeEventArgs e = new SerializeNodeEventArgs(nodeToLoad, xmlNode, xmlElem);
context.AdvTree.InvokeDeserializeNode(e);
}
}
}
context.RefXmlElement = xmlNode;
}
private static void LoadCells(Node parentNode, XmlElement xmlCells)
{
foreach(XmlNode xmlChild in xmlCells.ChildNodes)
{
if(xmlChild.Name==XmlCellName && xmlChild is XmlElement)
{
Cell cell=new Cell();
parentNode.Cells.Add(cell);
ElementSerializer.Deserialize(cell, xmlChild as XmlElement);
// Load images if any
foreach(XmlElement xmlImage in xmlChild.ChildNodes)
{
if(xmlImage.Name==XmlCellImagesName)
{
ElementSerializer.Deserialize(cell.Images, xmlImage);
break;
}
}
}
}
}
#endregion
}
/// <summary>
/// Provides context information for serialization.
/// </summary>
public class NodeSerializationContext
{
/// <summary>
/// Gets or sets reference to context parent XmlElement when serializing or actual Node element when deserializing.
/// </summary>
public System.Xml.XmlElement RefXmlElement = null;
/// <summary>
/// Gets or sets whether SerializeNode event handler has been defined and whether event should be fired.
/// </summary>
public bool HasSerializeNodeHandlers = false;
/// <summary>
/// Gets or sets whether DeserializeNode event handler has been defined and whether event should be fired.
/// </summary>
public bool HasDeserializeNodeHandlers = false;
/// <summary>
/// Provides access to serializer.
/// </summary>
public AdvTree AdvTree = null;
}
}

View File

@ -0,0 +1,329 @@
using System;
using System.ComponentModel.Design;
using System.Drawing;
using System.ComponentModel;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Rendering;
using System.Windows.Forms;
namespace DevComponents.AdvTree
{
/// <summary>
/// Represents class for static tree utilities.
/// </summary>
public class Utilities
{
/// <summary>
/// Initializes control with default settings for connectors and nodes.
/// </summary>
/// <param name="tree">Control to initialize.</param>
public static void InitializeTree(AdvTree tree)
{
InitializeTree(tree,new ComponentFactory());
}
/// <summary>
/// Initializes control with default settings for connectors and nodes.
/// </summary>
/// <param name="tree">Control to initialize.</param>
/// <param name="factory">Factory to use to create new instances of objects.</param>
public static void InitializeTree(AdvTree tree, ComponentFactory factory)
{
//tree.RootConnector=factory.CreateComponent(typeof(NodeConnector)) as NodeConnector;
//tree.RootConnector.LineWidth=1;
//tree.RootConnector.LineColor = SystemColors.ControlText;
tree.NodesConnector=factory.CreateComponent(typeof(NodeConnector)) as NodeConnector;
tree.NodesConnector.LineWidth=1;
tree.NodesConnector.LineColor=SystemColors.ControlText;
tree.BackColor = SystemColors.Window;
//eStyleBorderType border=eStyleBorderType.Solid;
ElementStyle style=factory.CreateComponent(typeof(ElementStyle)) as ElementStyle;
//style.BackColorSchemePart=eColorSchemePart.BarBackground;
//style.BackColor2SchemePart=eColorSchemePart.BarBackground2;
//style.BackColorGradientAngle=90;
//style.CornerDiameter=4;
//style.CornerType=eCornerType.Rounded;
//style.BorderLeft=border;
//style.BorderLeftWidth=1;
//style.BorderTop=border;
//style.BorderTopWidth=1;
//style.BorderBottom=border;
//style.BorderBottomWidth=1;
//style.BorderRight=border;
//style.BorderRightWidth=1;
//style.BorderColorSchemePart=eColorSchemePart.BarDockedBorder;
//style.PaddingBottom=3;
//style.PaddingLeft=3;
//style.PaddingRight=3;
//style.PaddingTop=3;
style.TextColor = SystemColors.ControlText;
tree.Styles.Add(style);
tree.NodeStyle=style;
tree.BackgroundStyle.Class = ElementStyleClassKeys.TreeBorderKey;
tree.AccessibleRole = AccessibleRole.Outline;
}
/// <summary>
/// Creates new style and adds it to styles collection
/// </summary>
/// <param name="tree">Tree to assign style to</param>
/// <param name="factory">Style factory</param>
/// <param name="backColor"></param>
/// <param name="backColor2"></param>
/// <param name="gradientAngle"></param>
/// <param name="textColor"></param>
internal static ElementStyle CreateStyle(ComponentFactory factory, string description, Color borderColor, Color backColor, Color backColor2, int gradientAngle, Color textColor)
{
eStyleBorderType border=eStyleBorderType.Solid;
ElementStyle style=factory.CreateComponent(typeof(ElementStyle)) as ElementStyle;
style.Description = description;
style.BackColor = backColor;
style.BackColor2=backColor2;
style.BackColorGradientAngle=gradientAngle;
style.CornerDiameter=4;
style.CornerType=eCornerType.Square;
style.BorderLeft=border;
style.BorderLeftWidth=1;
style.BorderTop=border;
style.BorderTopWidth=1;
style.BorderBottom=border;
style.BorderBottomWidth=1;
style.BorderRight=border;
style.BorderRightWidth=1;
style.BorderColor=borderColor;
style.PaddingBottom=1;
style.PaddingLeft=1;
style.PaddingRight=1;
style.PaddingTop=1;
style.TextColor=textColor;
return style;
}
/// <summary>
/// Returns reference to a node that is hosting given control.
/// </summary>
/// <param name="tree">Reference to the AdvTree control instance</param>
/// <param name="c">Control instance to look for</param>
/// <returns>Reference to a node hosting control or null if node could not be found</returns>
public static Node FindNodeForControl(AdvTree tree, System.Windows.Forms.Control c)
{
if(tree==null || c==null || tree.Nodes.Count==0)
return null;
Node node = tree.Nodes[0];
while(node!=null)
{
foreach(Cell cell in node.Cells)
{
if(cell.HostedControl==c)
return node;
}
node = node.NextVisibleNode;
}
return null;
}
internal static int CompareAlpha(string t, string t2)
{
return string.Compare(t, t2, StringComparison.CurrentCulture);
}
internal static bool StartsWithNumber(string s)
{
if (s.Length > 0 && char.IsDigit(s[0]))
return true;
return false;
}
internal static int CompareAlphaNumeric(string t, string t2)
{
if (Utilities.StartsWithNumber(t) && Utilities.StartsWithNumber(t2))
{
long l = GetNumber(t), l2 = GetNumber(t2);
int i = l.CompareTo(l2);
if (i != 0)
return i;
}
#if FRAMEWORK20
return string.Compare(t, t2, StringComparison.CurrentCulture);
#else
return string.Compare(t, t2);
#endif
}
internal static long GetNumber(string s)
{
long l = 0;
int start = 0, end = 0;
for (int i = 0; i < s.Length; i++)
{
if (char.IsDigit(s[i]))
{
end = i;
}
else
break;
}
#if FRAMEWORK20
long.TryParse(s.Substring(start, end - start + 1), out l);
#else
try
{
l = long.Parse(s.Substring(start, end - start + 1));
}
catch { }
#endif
return l;
}
internal static string StripNonNumeric(string p)
{
string s = "";
string decimalSeparator = NumberDecimalSeparator;
string groupSeparator = NumberGroupSeparator;
for (int i = 0; i < p.Length; i++)
{
if (p[i].ToString() == decimalSeparator || p[i].ToString() == groupSeparator || p[i] >= '0' && p[i] <= '9' || i == 0 && p[i] == '-')
s += p[i];
else if (s.Length > 0) break;
}
return s;
}
private static string NumberDecimalSeparator
{
get
{
#if FRAMEWORK20
return DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture().NumberFormat.NumberDecimalSeparator;
#else
return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
#endif
}
}
private static string NumberGroupSeparator
{
get
{
#if FRAMEWORK20
return DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture().NumberFormat.NumberGroupSeparator;
#else
return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator;
#endif
}
}
}
#region ComponentFactory
/// <summary>
/// Represents internal component factory with design-time support.
/// </summary>
public class ComponentFactory
{
private IDesignerHost m_Designer=null;
/// <summary>
/// Creates new instance of the class.
/// </summary>
/// <param name="designer">Reference to DesignerHost to use for creation of new components.</param>
public ComponentFactory(IDesignerHost designer)
{
m_Designer=designer;
}
/// <summary>
/// Creates new instance of the class.
/// </summary>
public ComponentFactory() {}
/// <summary>
/// Creates component and returns reference to the new instance.
/// </summary>
/// <param name="type">Type that identifies component to create.</param>
/// <returns>New instance of the component.</returns>
public object CreateComponent(Type type)
{
object o=null;
if(m_Designer!=null)
o=m_Designer.CreateComponent(type);
else
o=type.Assembly.CreateInstance(type.FullName);
return o;
}
}
#endregion
#region Padding Class
/// <summary>
/// Represents class that holds padding information for user interface elements.
/// </summary>
public class Padding
{
/// <summary>
/// Gets or sets padding on left side. Default value is 0
/// </summary>
public int Left = 0;
/// <summary>
/// Gets or sets padding on right side. Default value is 0
/// </summary>
public int Right = 0;
/// <summary>
/// Gets or sets padding on top side. Default value is 0
/// </summary>
public int Top = 0;
/// <summary>
/// Gets or sets padding on bottom side. Default value is 0
/// </summary>
public int Bottom = 0;
/// <summary>
/// Creates new instance of the class and initializes it.
/// </summary>
/// <param name="left">Left padding</param>
/// <param name="right">Right padding</param>
/// <param name="top">Top padding</param>
/// <param name="bottom">Bottom padding</param>
public Padding(int left, int right, int top, int bottom)
{
this.Left = left;
this.Right = right;
this.Top = top;
this.Bottom = bottom;
}
/// <summary>
/// Gets amount of horizontal padding (Left+Right)
/// </summary>
[Browsable(false)]
public int Horizontal
{
get { return this.Left + this.Right; }
}
/// <summary>
/// Gets amount of vertical padding (Top+Bottom)
/// </summary>
[Browsable(false)]
public int Vertical
{
get { return this.Top + this.Bottom; }
}
/// <summary>
/// Gets whether Padding is empty.
/// </summary>
public bool IsEmpty
{
get
{
return this.Left == 0 && this.Right == 0 && this.Top == 0 && this.Bottom == 0;
}
}
}
#endregion
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,305 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Controls
{
/// <summary>
/// Data storage class for clock hand visual style.
/// </summary>
[Description("Clock Hand Style"),
TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class ClockHandStyleData : INotifyPropertyChanged
{
private bool _DrawOverCap;
/// <summary>
/// Gets or sets a value indicating whether the hand is drawn over the cap.
/// </summary>
[DefaultValue(false),
Category("Appearance"),
Description("Indicates whether the hand is drawn over the cap.")]
public bool DrawOverCap
{
get { return _DrawOverCap; }
set { _DrawOverCap = value; }
}
private void ColorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
private ColorData _HandColor;
/// <summary>
/// Gets or sets the hand color data for this hand.
/// </summary>
[Category("Appearance"),
Description("The hand color data for this hand.")]
public ColorData HandColor
{
get { return _HandColor; }
set
{
if (value != _HandColor)
{
if (_HandColor != null) _HandColor.PropertyChanged -= ColorPropertyChanged;
_HandColor = value;
if (_HandColor != null) _HandColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("HandColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetHandColor()
{
HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f);
}
private eHandStyles _HandStyle;
/// <summary>
/// Gets or sets the hand style for this clock hand. Default value is Style1.
/// </summary>
[DefaultValue(eHandStyles.Style1),
Category("Appearance"),
Description("The hand style for this clock hand.")]
public eHandStyles HandStyle
{
get { return _HandStyle; }
set
{
if (value != _HandStyle)
{
_HandStyle = value;
OnPropertyChanged(new PropertyChangedEventArgs("HandStyle"));
}
}
}
private float _Length;
/// <summary>
/// Gets or sets the length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle. Default value is 1.0.
/// </summary>
[DefaultValue(1.0f),
Category("Appearance"),
Description("The length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle.")]
public float Length
{
get { return _Length; }
set
{
if (value != _Length)
{
_Length = value;
OnPropertyChanged(new PropertyChangedEventArgs("Length"));
}
}
}
private float _Width;
/// <summary>
/// Gets or sets the width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle. Default value is 0.1.
/// </summary>
[DefaultValue(0.1f),
Category("Appearance"),
Description("The width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle.")]
public float Width
{
get { return _Width; }
set
{
if (value != _Width)
{
_Width = value;
OnPropertyChanged(new PropertyChangedEventArgs("Width"));
}
}
}
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes a new instance of the ClockHand class.
/// </summary>
public ClockHandStyleData()
{
_DrawOverCap = false;
_HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f);
_HandStyle = eHandStyles.Style1;
_Length = 1.0f;
_Width = 0.1f;
}
/// <summary>
/// Initializes a new instance of the ClockHand class.
/// </summary>
/// <param name="handStyle">The hand style for this item.</param>
/// <param name="length">The length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle</param>
/// <param name="width">The width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle.</param>
public ClockHandStyleData(eHandStyles handStyle, float length, float width)
{
_DrawOverCap = false;
_HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f);
_HandStyle = handStyle;
_Length = length;
_Width = width;
}
/// <summary>
/// Indicates whether the specified point is contained within the bounds of this hand.
/// </summary>
/// <param name="boundingRect">The bounding rectangle of the parent clock control.</param>
/// <param name="angle">The clockwise angle for this clock hand in degrees from the 12 o'clock position.</param>
/// <param name="pt">A Point that represents the point to test.</param>
/// <returns></returns>
public virtual bool ContainsPoint(RectangleF boundingRect, float angle, Point pt)
{
GraphicsPath path;
bool ret;
path = GenerateHandPath(boundingRect, angle);
ret = path.IsVisible(pt);
path.Dispose();
return ret;
}
/// <summary>
/// Generates a scaled and rotated graphics path based on the given style, rectangle and angle.
/// </summary>
/// <param name="boundingRect">The bounding rectangle of the parent clock control.</param>
/// <param name="angle">The clockwise angle for this clock hand in degrees from the 12 o'clock position.</param>
/// <returns></returns>
public GraphicsPath GenerateHandPath(RectangleF boundingRect, float angle)
{
GraphicsPath path = new GraphicsPath();
RectangleF rect;
Matrix matrix;
float scaleFactor;
PointF[] pts;
switch (_HandStyle)
{
case eHandStyles.Style1:
pts = new PointF[4];
pts[0].X = -0.5f;
pts[0].Y = 0.0f;
pts[1].X = -0.5f;
pts[1].Y = -1.0f;
pts[2].X = 0.5f;
pts[2].Y = -1.0f;
pts[3].X = 0.5f;
pts[3].Y = 0.0f;
path.AddPolygon(pts);
break;
case eHandStyles.Style2:
pts = new PointF[4];
pts[0].X = -0.4f;
pts[0].Y = 0.25f;
pts[1].X = -0.4f;
pts[1].Y = -1.0f;
pts[2].X = 0.4f;
pts[2].Y = -1.0f;
pts[3].X = 0.4f;
pts[3].Y = 0.25f;
path.AddPolygon(pts);
break;
case eHandStyles.Style3:
pts = new PointF[4];
pts[0].X = -0.5f;
pts[0].Y = 0.0f;
pts[1].X = -0.0125f;
pts[1].Y = -1.0f;
pts[2].X = 0.0125f;
pts[2].Y = -1.0f;
pts[3].X = 0.5f;
pts[3].Y = 0.0f;
path.AddPolygon(pts);
break;
case eHandStyles.Style4:
path.FillMode = FillMode.Winding;
pts = new PointF[4];
pts[0].X = -0.5f;
pts[0].Y = -0.05f;
pts[1].X = -0.5f;
pts[1].Y = -1.0f;
pts[2].X = 0.5f;
pts[2].Y = -1.0f;
pts[3].X = 0.5f;
pts[3].Y = -0.05f;
path.AddPolygon(pts);
rect = new RectangleF(-5.0f, -0.06f, 10.0f, 0.12f);
path.AddEllipse(rect);
break;
}
scaleFactor = Math.Min(boundingRect.Width, boundingRect.Height) / 2.0f;
matrix = new Matrix();
matrix.Translate(boundingRect.X + boundingRect.Width * 0.5f, boundingRect.Y + boundingRect.Width * 0.5f);
matrix.Rotate(angle);
matrix.Scale(scaleFactor * Width, scaleFactor * Length);
path.Transform(matrix);
matrix.Dispose();
return path;
}
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
/// <summary>
/// Enumeration containing the available hand styles.
/// </summary>
public enum eHandStyles
{
/// <summary>
/// Style 1.
/// </summary>
Style1,
/// <summary>
/// Style 2.
/// </summary>
Style2,
/// <summary>
/// Style 3.
/// </summary>
Style3,
/// <summary>
/// Style 4.
/// </summary>
Style4,
}
}

View File

@ -0,0 +1,659 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
namespace DevComponents.DotNetBar.Controls
{
/// <summary>
/// Data storage class for clock visual styles.
/// </summary>
[Description("Clock Style"),
TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class ClockStyleData : IDisposable, INotifyPropertyChanged
{
private eClockStyles _Style;
/// <summary>
/// Gets or sets the PredefinedStyles value for this style.
/// </summary>
[Browsable(false)]
public eClockStyles Style
{
get { return _Style; }
set
{
if (value != _Style)
{
_Style = value;
OnPropertyChanged(new PropertyChangedEventArgs("Style"));
}
}
}
private eClockShapes _ClockShape;
/// <summary>
/// Gets or sets the clock shape value for this style.
/// </summary>
[DefaultValue(eClockShapes.Round),
Category("Appearance"),
Description("The clock shape for this style.")]
public eClockShapes ClockShape
{
get { return _ClockShape; }
set
{
if (value != _ClockShape)
{
_ClockShape = value;
OnPropertyChanged(new PropertyChangedEventArgs("ClockShape"));
}
}
}
private void ColorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (_Parent != null) _Parent.Invalidate();
}
private ColorData _BezelColor;
/// <summary>
/// Gets or sets the bezel color data for this style.
/// </summary>
[Category("Appearance"),
Description("The bezel color data for this style.")]
public ColorData BezelColor
{
get { return _BezelColor; }
set
{
if (value != _BezelColor)
{
if (_BezelColor != null) _BezelColor.PropertyChanged -= ColorPropertyChanged;
_BezelColor = value;
if (_BezelColor != null) _BezelColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("BezelColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetBezelColor()
{
BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(255, 255, 255), Color.FromArgb(152, 152, 152), Color.FromArgb(120, 120, 120), 1.0f, 45.0f);
}
private float _BezelWidth;
/// <summary>
/// Gets or sets the width of clock bezel as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.03f),
Category("Appearance"),
Description("The width of clock bezel as a percentage value ranging from 0.0 to 1.0.")]
public float BezelWidth
{
get { return _BezelWidth; }
set
{
if (value != _BezelWidth)
{
_BezelWidth = value;
OnPropertyChanged(new PropertyChangedEventArgs("BezelWidth"));
}
}
}
private ColorData _FaceColor;
/// <summary>
/// Gets or sets the face color data for this style.
/// </summary>
[Category("Appearance"),
Description("The face color data for this style.")]
public ColorData FaceColor
{
get { return _FaceColor; }
set
{
if (value != _FaceColor)
{
if (_FaceColor != null) _FaceColor.PropertyChanged -= ColorPropertyChanged;
_FaceColor = value;
if (_FaceColor != null) _FaceColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("FaceColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetFaceColor()
{
FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(191, 204, 213), Color.FromArgb(255, 255, 255), Color.FromArgb(135, 145, 161), 1.0f, 45.0f);
}
private Image _FaceBackgroundImage;
/// <summary>
/// Gets or sets the face background image for this style.
/// </summary>
[DefaultValue(null),
Category("Appearance"),
Description("The face background image for this style.")]
public Image FaceBackgroundImage
{
get { return _FaceBackgroundImage; }
set
{
if (value != _FaceBackgroundImage)
{
_FaceBackgroundImage = value;
OnPropertyChanged(new PropertyChangedEventArgs("FaceBackgroundImage"));
}
}
}
private ClockHandStyleData _HourHandStyle;
/// <summary>
/// Gets or sets the hour hand style for this style.
/// </summary>
[Category("Appearance"),
Description("The hour hand style for this style.")]
public ClockHandStyleData HourHandStyle
{
get { return _HourHandStyle; }
set
{
if (value != _HourHandStyle)
{
if (_HourHandStyle != null) _HourHandStyle.PropertyChanged -= ColorPropertyChanged;
_HourHandStyle = value;
if (_HourHandStyle != null) _HourHandStyle.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("HourHandStyle"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetHourHandStyle()
{
HourHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.55f, 0.01f);
}
private ClockHandStyleData _MinuteHandStyle;
/// <summary>
/// Gets or sets the minute hand style for this style.
/// </summary>
[Category("Appearance"),
Description("The minute hand style for this style.")]
public ClockHandStyleData MinuteHandStyle
{
get { return _MinuteHandStyle; }
set
{
if (value != _MinuteHandStyle)
{
if (_MinuteHandStyle != null) _MinuteHandStyle.PropertyChanged -= ColorPropertyChanged;
_MinuteHandStyle = value;
if (_MinuteHandStyle != null) _MinuteHandStyle.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("MinuteHandStyle"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetMinuteHandStyle()
{
MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.8f, 0.01f);
}
private ClockHandStyleData _SecondHandStyle;
/// <summary>
/// Gets or sets the second hand style for this style.
/// </summary>
[Category("Appearance"),
Description("The second hand style for this style.")]
public ClockHandStyleData SecondHandStyle
{
get { return _SecondHandStyle; }
set
{
if (value != _SecondHandStyle)
{
if (_SecondHandStyle != null) _SecondHandStyle.PropertyChanged -= ColorPropertyChanged;
_SecondHandStyle = value;
if (_SecondHandStyle != null) _SecondHandStyle.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("SecondHandStyle"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetSecondHandStyle()
{
SecondHandStyle = new ClockHandStyleData(eHandStyles.Style2, 0.8f, 0.005f);
}
private ColorData _CapColor;
/// <summary>
/// Gets or sets the center cap color data for this style.
/// </summary>
[Category("Appearance"),
Description("The center cap color data for this style.")]
public ColorData CapColor
{
get { return _CapColor; }
set
{
if (value != _CapColor)
{
if (_CapColor != null) _CapColor.PropertyChanged -= ColorPropertyChanged;
_CapColor = value;
if (_CapColor != null) _CapColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("CapColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetCapColor()
{
CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f);
}
private float _CapSize;
/// <summary>
/// Gets or sets the center cap diameter as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.03f),
Category("Appearance"),
Description("The center cap diameter as a percentage value ranging from 0.0 to 1.0.")]
public float CapSize
{
get { return _CapSize; }
set
{
if (value != _CapSize)
{
_CapSize = value;
OnPropertyChanged(new PropertyChangedEventArgs("CapSize"));
}
}
}
private Color _NumberColor;
/// <summary>
/// Gets or sets the face number color for this style.
/// </summary>
[DefaultValue(typeof(Color), "139, 158, 168"),
Category("Appearance"),
Description("The face number color for this style.")]
public Color NumberColor
{
get { return _NumberColor; }
set
{
if (value != _NumberColor)
{
_NumberColor = value;
OnPropertyChanged(new PropertyChangedEventArgs("NumberColor"));
}
}
}
private Font _NumberFont;
/// <summary>
/// Gets or sets the center cap color data for this style.
/// </summary>
[Category("Appearance"),
Description("The face number font for this style.")]
public Font NumberFont
{
get { return _NumberFont; }
set
{
if (value != _NumberFont)
{
_NumberFont = value;
OnPropertyChanged(new PropertyChangedEventArgs("NumberFont"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetNumberFont()
{
_NumberFont = new Font("Microsoft Sans Serif", 8, FontStyle.Regular, GraphicsUnit.Pixel);
}
private ColorData _LargeTickColor;
/// <summary>
/// Gets or sets the large tick color data for this style.
/// </summary>
[Category("Appearance"),
Description("The large tick color data for this style.")]
public ColorData LargeTickColor
{
get { return _LargeTickColor; }
set
{
if (value != _LargeTickColor)
{
if (_LargeTickColor != null) _LargeTickColor.PropertyChanged -= ColorPropertyChanged;
_LargeTickColor = value;
if (_LargeTickColor != null) _LargeTickColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("LargeTickColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetLargeTickColor()
{
LargeTickColor = new ColorData(eBrushTypes.Centered, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(255, 255, 255), 1.0f);
}
private float _LargeTickLength;
/// <summary>
/// Gets or sets the large tick length as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.06f),
Category("Appearance"),
Description("The large tick length as a percentage value ranging from 0.0 to 1.0.")]
public float LargeTickLength
{
get { return _LargeTickLength; }
set
{
if (value != _LargeTickLength)
{
_LargeTickLength = value;
OnPropertyChanged(new PropertyChangedEventArgs("LargeTickLength"));
}
}
}
private float _LargeTickWidth;
/// <summary>
/// Gets or sets the large tick width as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.02f),
Category("Appearance"),
Description("The large tick width as a percentage value ranging from 0.0 to 1.0.")]
public float LargeTickWidth
{
get { return _LargeTickWidth; }
set
{
if (value != _LargeTickWidth)
{
_LargeTickWidth = value;
OnPropertyChanged(new PropertyChangedEventArgs("LargeTickWidth"));
}
}
}
private ColorData _SmallTickColor;
/// <summary>
/// Gets or sets the small tick color data for this style.
/// </summary>
[Category("Appearance"),
Description("The small tick color data for this style.")]
public ColorData SmallTickColor
{
get { return _SmallTickColor; }
set
{
if (value != _SmallTickColor)
{
if (_SmallTickColor != null) _SmallTickColor.PropertyChanged -= ColorPropertyChanged;
_SmallTickColor = value;
if (_SmallTickColor != null) _SmallTickColor.PropertyChanged += ColorPropertyChanged;
OnPropertyChanged(new PropertyChangedEventArgs("SmallTickColor"));
}
}
}
/// <summary>
/// Resets the property to default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetSmallTickColor()
{
SmallTickColor = new ColorData(eBrushTypes.Centered, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(255, 255, 255), 1.0f);
}
private float _SmallTickLength;
/// <summary>
/// Gets or sets the small tick length as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.02f),
Category("Appearance"),
Description("The small tick length as a percentage value ranging from 0.0 to 1.0.")]
public float SmallTickLength
{
get { return _SmallTickLength; }
set
{
if (value != _SmallTickLength)
{
_SmallTickLength = value;
OnPropertyChanged(new PropertyChangedEventArgs("SmallTickLength"));
}
}
}
private float _SmallTickWidth;
/// <summary>
/// Gets or sets the small tick width as a percentage value ranging from 0.0 to 1.0.
/// </summary>
[DefaultValue(0.02f),
Category("Appearance"),
Description("The small tick width as a percentage value ranging from 0.0 to 1.0.")]
public float SmallTickWidth
{
get { return _SmallTickWidth; }
set
{
if (value != _SmallTickWidth)
{
_SmallTickWidth = value;
OnPropertyChanged(new PropertyChangedEventArgs("SmallTickWidth"));
}
}
}
private int _GlassAngle;
/// <summary>
/// Gets or sets the overlay glass angle, in degrees for this style.
/// </summary>
[DefaultValue(20),
Category("Appearance"),
Description("The overlay angle, in degrees for this style.")]
public int GlassAngle
{
get { return _GlassAngle; }
set
{
if (value != _GlassAngle)
{
_GlassAngle = value;
OnPropertyChanged(new PropertyChangedEventArgs("_GlassAngle"));
}
}
}
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes a new instance of the ClockStyle class.
/// </summary>
public ClockStyleData()
{
LoadStyle(eClockStyles.Style1);
}
private AnalogClockControl _Parent = null;
/// <summary>
/// Gets the parent of the style.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AnalogClockControl Parent
{
get { return _Parent; }
internal set { _Parent = value; }
}
/// <summary>
/// Initializes a new instance of the ClockStyle class.
/// </summary>
/// <param name="style">Predefined style from the PredefinedStyles enum.</param>
public ClockStyleData(eClockStyles style)
{
LoadStyle(style);
}
/// <summary>
/// Initializes a new instance of the ClockStyle class.
/// </summary>
/// <param name="style">Predefined style from the PredefinedStyles enum.</param>
public ClockStyleData(eClockStyles style, AnalogClockControl parent)
{
LoadStyle(style);
_Parent = parent;
}
/// <summary>
/// Releases all resources used by the class.
/// </summary>
public void Dispose()
{
if (_FaceBackgroundImage != null)
_FaceBackgroundImage.Dispose();
if (_NumberFont != null)
_NumberFont.Dispose();
}
/// <summary>
/// Loads a predefined style
/// </summary>
/// <param name="style">The predefined style to load.</param>
private void LoadStyle(eClockStyles style)
{
_Style = style;
switch (style)
{
case eClockStyles.Style1:
case eClockStyles.Custom:
_ClockShape = eClockShapes.Round;
BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(255, 255, 255), Color.FromArgb(152, 152, 152), Color.FromArgb(120, 120, 120), 0.01f);
_BezelWidth = 0.03f;
FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(191, 204, 213), Color.FromArgb(255, 255, 255), Color.FromArgb(135, 145, 161), 0.01f, 45.0f);
_FaceBackgroundImage = null;
HourHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.55f, 0.015f);
MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.8f, 0.01f);
SecondHandStyle = new ClockHandStyleData(eHandStyles.Style2, 0.8f, 0.005f);
CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f);
_CapSize = 0.03f;
_NumberColor = Color.FromArgb(139, 158, 168);
_NumberFont = new Font("Microsoft Sans Serif", 12, FontStyle.Regular, GraphicsUnit.Pixel);
LargeTickColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(128, 255, 255, 255), 0.01f);
_LargeTickLength = 0.06f;
_LargeTickWidth = 0.02f;
SmallTickColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(128, 255, 255, 255), 0.01f);
_SmallTickLength = 0.02f;
_SmallTickWidth = 0.02f;
_GlassAngle = -20;
break;
case eClockStyles.Style2:
_ClockShape = eClockShapes.Round;
BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(80, 80, 80), Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), 0.0f, 90.0f);
_BezelWidth = 0.03f;
FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(225, 225, 225), Color.FromArgb(240, 240, 240), Color.FromArgb(0, 0, 0), 0.0f, 90.0f);
_FaceBackgroundImage = null;
HourHandStyle = new ClockHandStyleData(eHandStyles.Style3, 0.45f, 0.175f);
HourHandStyle.HandColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(0, 0, 0), Color.FromArgb(80, 80, 80), Color.FromArgb(64, 0, 0, 0), 0.01f, 90.0f);
MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style3, 0.75f, 0.175f);
MinuteHandStyle.HandColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(0, 0, 0), Color.FromArgb(80, 80, 80), Color.FromArgb(64, 0, 0, 0), 0.01f, 90.0f);
SecondHandStyle = new ClockHandStyleData(eHandStyles.Style4, 0.9f, 0.01f);
SecondHandStyle.HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(255, 0, 0), Color.FromArgb(255, 0, 0), Color.FromArgb(128, 192, 0, 0), 0.01f);
_SecondHandStyle.DrawOverCap = true;
CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(255, 255, 255), Color.FromArgb(255, 255, 255), Color.FromArgb(223, 0, 0, 0), 0.01f);
_CapSize = 0.1f;
_NumberColor = Color.FromArgb(0, 0, 0);
_NumberFont = new Font("Trebuchet MS", 12, FontStyle.Regular, GraphicsUnit.Pixel);
LargeTickColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), Color.FromArgb(64, 0, 0, 0), 0.01f);
_LargeTickLength = 0.06f;
_LargeTickWidth = 0.01f;
SmallTickColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), Color.FromArgb(64, 0, 0, 0), 0.01f);
_SmallTickLength = 0.01f;
_SmallTickWidth = 0.01f;
_GlassAngle = 0;
break;
}
}
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
if (_Parent != null) _Parent.Invalidate();
}
}
/// <summary>
/// Enumeration containing the predefined clock styles.
/// </summary>
public enum eClockStyles
{
/// <summary>
/// Style 1. Default style,
/// </summary>
Style1,
/// <summary>
/// Style 2.
/// </summary>
Style2,
/// <summary>
/// No predefined style.
/// </summary>
Custom
}
/// <summary>
/// Enumeration containing the predefined clock shapes.
/// </summary>
public enum eClockShapes
{
/// <summary>
/// Round clock shape.
/// </summary>
Round
}
}

View File

@ -0,0 +1,442 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.DotNetBar.Controls
{
/// <summary>
/// Data storage and utility class for defining gradient colors.
/// </summary>
[Description("Color Data Class"),
TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class ColorData : INotifyPropertyChanged
{
private Color _BorderColor;
/// <summary>
/// Gets or sets the border color for this item. Default value is white.
/// </summary>
[DefaultValue(typeof(Color), "255, 255, 255"),
Category("Appearance"),
Description("The border color for this item.")]
public Color BorderColor
{
get { return _BorderColor; }
set
{
if (value != _BorderColor)
{
_BorderColor = value;
OnPropertyChanged(new PropertyChangedEventArgs("BorderColor"));
}
}
}
private float _BorderWidth;
/// <summary>
/// Gets or sets the border width for this item. Default value is 0.
/// </summary>
[DefaultValue(0.0f),
Category("Appearance"),
Description("The border width for this item.")]
public float BorderWidth
{
get { return _BorderWidth; }
set
{
if (value != _BorderWidth)
{
_BorderWidth = value;
OnPropertyChanged(new PropertyChangedEventArgs("BorderWidth"));
}
}
}
private float _BrushAngle;
/// <summary>
/// Gets or sets the brush angle for this item. Only applies to Linear and Reflected brush types. Default value is 0.
/// </summary>
[DefaultValue(0.0f),
Category("Appearance"),
Description("The brush angle for this item. Only applies to Linear and Reflected brush types.")]
public float BrushAngle
{
get { return _BrushAngle; }
set
{
if (value != _BrushAngle)
{
_BrushAngle = value;
OnPropertyChanged(new PropertyChangedEventArgs("BrushAngle"));
}
}
}
private float _BrushSBSFocus;
/// <summary>
/// Gets or sets the brush SigmaBellShape focus for this item. Only applies to Reflected brush types. Default value is 0.5.
/// </summary>
[DefaultValue(0.5f),
Category("Appearance"),
Description("The brush SigmaBellShape focus for this item. Only applies to Linear and Reflected brush types.")]
public float BrushSBSFocus
{
get { return _BrushSBSFocus; }
set
{
if (value != _BrushSBSFocus)
{
_BrushSBSFocus = value;
OnPropertyChanged(new PropertyChangedEventArgs("BrushSBSFocus"));
}
}
}
private float _BrushSBSScale;
/// <summary>
/// Gets or sets the brush SigmaBellShape scale for this item. Only applies to Reflected brush types. Default value is 0.5.
/// </summary>
[DefaultValue(0.5f),
Category("Appearance"),
Description("The brush SigmaBellShape scale for this item. Only applies to Linear and Reflected brush types.")]
public float BrushSBSScale
{
get { return _BrushSBSScale; }
set
{
if (value != _BrushSBSScale)
{
_BrushSBSScale = value;
OnPropertyChanged(new PropertyChangedEventArgs("BrushSBSScale"));
}
}
}
private eBrushTypes _BrushType;
/// <summary>
/// Gets or sets the brush type for this item. Default value is Solid.
/// </summary>
[DefaultValue(eBrushTypes.Solid),
Category("Appearance"),
Description("The brush type for this item.")]
public eBrushTypes BrushType
{
get { return _BrushType; }
set
{
if (value != _BrushType)
{
_BrushType = value;
OnPropertyChanged(new PropertyChangedEventArgs("BrushType"));
}
}
}
private Color _Color1;
/// <summary>
/// Gets or sets the first color for this item. Default value is white.
/// </summary>
[DefaultValue(typeof(Color), "255, 255, 255"),
Category("Appearance"),
Description("The first color for this item.")]
public Color Color1
{
get { return _Color1; }
set
{
if (value != _Color1)
{
_Color1 = value;
OnPropertyChanged(new PropertyChangedEventArgs("Color1"));
}
}
}
private Color _Color2;
/// <summary>
/// Gets or sets the second color for this item. Default value is white.
/// </summary>
[DefaultValue(typeof(Color), "255, 255, 255"),
Category("Appearance"),
Description("The second color for this item.")]
public Color Color2
{
get { return _Color2; }
set
{
if (value != _Color2)
{
_Color2 = value;
OnPropertyChanged(new PropertyChangedEventArgs("Color2"));
}
}
}
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Creates new instance of the object.
/// </summary>
public ColorData()
{
LoadData(eBrushTypes.Solid, Color.White, Color.White, Color.White, 0.0f, 0.0f, 0.5f, 1.0f);
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="color1">The first color for this entry.</param>
/// <param name="color2">The second color for this entry.</param>
public ColorData(eBrushTypes brushType, Color color1, Color color2)
{
LoadData(brushType, color1, color2, Color.White, 0.0f, 0.0f, 0.5f, 1.0f);
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="color1">The first color for this entry.</param>
/// <param name="color2">The second color for this entry.</param>
/// <param name="borderColor">The border color for this entry.</param>
/// <param name="borderWidth">The border width for this entry.</param>
public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth)
{
LoadData(brushType, color1, color2, borderColor, borderWidth, 0.0f, 0.5f, 1.0f);
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="color1">The first color for this entry.</param>
/// <param name="color2">The second color for this entry.</param>
/// <param name="borderColor">The border color for this entry.</param>
/// <param name="borderWidth">The border width for this entry.</param>
/// <param name="brushAngle">The gradient angle.</param>
public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushAngle)
{
LoadData(brushType, color1, color2, borderColor, borderWidth, brushAngle, 0.5f, 1.0f);
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="color1">The first color for this entry.</param>
/// <param name="color2">The second color for this entry.</param>
/// <param name="borderColor">The border color for this entry.</param>
/// <param name="borderWidth">The border width for this entry.</param>
/// <param name="brushSBSFocus">The focus for the SigmaBellShape.</param>
/// <param name="brushSBSScale">The scale for the SigmaBellShape.</param>
public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushSBSFocus, float brushSBSScale)
{
LoadData(brushType, color1, color2, borderColor, borderWidth, 0.0f, brushSBSFocus, brushSBSScale);
}
/// <summary>
/// Loads data into the class, called by constructors.
/// </summary>
/// <param name="color1">The first color for this entry.</param>
/// <param name="color2">The second color for this entry.</param>
/// <param name="borderColor">The border color for this entry.</param>
/// <param name="borderWidth">The border width for this entry.</param>
/// <param name="brushSBSFocus">The focus for the SigmaBellShape.</param>
/// <param name="brushSBSScale">The scale for the SigmaBellShape.</param>
protected void LoadData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushAngle, float brushSBSFocus, float brushSBSScale)
{
_BorderColor = borderColor;
_BorderWidth = borderWidth;
_Color1 = color1;
_Color2 = color2;
_BrushType = brushType;
_BrushAngle = brushAngle;
_BrushSBSFocus = brushSBSFocus;
_BrushSBSScale = brushSBSScale;
}
/// <summary>
/// Creates Pen object using the BorderColor and BorderWidth properties.
/// </summary>
public Pen GetBorderPen(float scaleFactor, PenAlignment penAlignment)
{
Pen pen = new Pen(_BorderColor, (float)Math.Round(_BorderWidth * scaleFactor, 0));
pen.Alignment = penAlignment;
return pen;
}
/// <summary>
/// Creates a brush of the type specified by BrushType.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
public Brush GetBrush(GraphicsPath path)
{
return GetBrush(path, new PointF(0.5f, 0.5f), _BrushAngle);
}
/// <summary>
/// Creates a brush of the type specified by BrushType.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="angle">The angle used for the gradients, allowing an override of BrushAngle</param>
public Brush GetBrush(GraphicsPath path, float angle)
{
return GetBrush(path, new PointF(0.5f, 0.5f), angle);
}
/// <summary>
/// Creates a brush of the type specified by BrushType.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="center">The center point of the gradient as a percentage value typically ranging from 0.0 to 1.0.</param>
public Brush GetBrush(GraphicsPath path, PointF center)
{
return GetBrush(path, center, _BrushAngle);
}
/// <summary>
/// Creates a brush of the type specified by BrushType.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="center">The center point of the gradient as a percentage value typically ranging from 0.0 to 1.0.</param>
/// <param name="angle">The angle used for the gradients, allowing an override of BrushAngle</param>
public Brush GetBrush(GraphicsPath path, PointF center, float angle)
{
RectangleF rect;
switch (_BrushType)
{
case eBrushTypes.Solid:
return new SolidBrush(_Color1);
case eBrushTypes.Linear:
path.Flatten();
rect = path.GetBounds();
if (rect.Width > 0.0f && rect.Height > 0.0f)
return new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false);
else
return null;
case eBrushTypes.Reflected:
LinearGradientBrush lBrush = new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false);
lBrush.SetSigmaBellShape(_BrushSBSFocus, _BrushSBSScale);
return lBrush;
case eBrushTypes.Centered:
PointF pt = new PointF();
rect = path.GetBounds();
PathGradientBrush pBrush = new PathGradientBrush(path);
pt.X = rect.X + rect.Width * center.X;
pt.Y = rect.Y + rect.Height * center.Y;
pBrush.CenterPoint = pt;
pBrush.CenterColor = _Color1;
pBrush.SurroundColors = new Color[] { _Color2 };
return pBrush;
default:
return new SolidBrush(_Color1);
}
}
/// <summary>
/// Creates SolidBrushObject using Color1.
/// </summary>
public Brush GetSolidBrush()
{
return new SolidBrush(_Color1);
}
/// <summary>
/// Creates a LinearGradientBrush object.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="angle">The gradient angle.</param>
public LinearGradientBrush GetLinearBrush(GraphicsPath path, int angle)
{
return new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false);
}
/// <summary>
/// Creates a PathGradientBrush object.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="center">The center point of the gradient.</param>
public PathGradientBrush GetCenteredBrush(GraphicsPath path, PointF center)
{
PathGradientBrush brush;
brush = new PathGradientBrush(path);
brush.CenterPoint = center;
brush.CenterColor = _Color1;
brush.SurroundColors = new Color[] { _Color2 };
return brush;
}
/// <summary>
/// Creates a LinearGradientBrush object.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="angle">The gradient angle.</param>
public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle)
{
return GetReflectedBrush(path, angle, 0.5f, 1.0f);
}
/// <summary>
/// Creates a LinearGradientBrush object.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="angle">The gradient angle.</param>
/// <param name="focus">The focus for the SigmaBellShape.</param>
public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle, float focus)
{
return GetReflectedBrush(path, angle, focus, 1.0f);
}
/// <summary>
/// Creates a LinearGradientBrush object.
/// </summary>
/// <param name="path">The graphics path used to construct the brush.</param>
/// <param name="angle">The gradient angle.</param>
/// <param name="focus">The focus for the SigmaBellShape.</param>
/// <param name="scale">The scale for the SigmaBellShape.</param>
public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle, float focus, float scale)
{
LinearGradientBrush brush = new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false);
brush.SetSigmaBellShape(focus, scale);
return brush;
}
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
/// <summary>
/// Enumeration containing predefined brush types for the ColorData class.
/// </summary>
public enum eBrushTypes
{
/// <summary>
/// Solid brush.
/// </summary>
Solid,
/// <summary>
/// Linear gradient brush.
/// </summary>
Linear,
/// <summary>
/// Centered path gradient brush.
/// </summary>
Centered,
/// <summary>
/// Reflected linear gradient brush.
/// </summary>
Reflected
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace DevComponents.DotNetBar
{
/// <summary>
/// Math helper class
/// </summary>
internal static class MathHelper
{
/// <summary>
/// Converts radians to degrees.
/// </summary>
/// <param name="radians">Value to be converted in radians.</param>
/// <returns>Converted value in degrees.</returns>
public static double GetDegrees(double radians)
{
return radians * (180.0 / Math.PI);
}
/// <summary>
/// Converts degrees to radians.
/// </summary>
/// <param name="degrees">Value to be converted in degrees.</param>
/// <returns>Converted value in radians.</returns>
public static double GetRadians(double degrees)
{
return degrees * (Math.PI / 180.0);
}
}
}

View File

@ -0,0 +1,772 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using System.Drawing;
namespace DevComponents.DotNetBar.Animation
{
internal abstract class Animation : Component
{
#region Events
/// <summary>
/// Occurs after animation has completed.
/// </summary>
public event EventHandler AnimationCompleted;
/// <summary>
/// Raises AnimationCompleted event.
/// </summary>
/// <param name="e">Provides event arguments.</param>
protected virtual void OnAnimationCompleted(EventArgs e)
{
EventHandler handler = AnimationCompleted;
if (handler != null)
handler(this, e);
}
#endregion
#region Constructor
private BackgroundWorker _Worker = null;
private AnimationEasing _EasingFunction = AnimationEasing.EaseOutQuad;
private double _Duration = 300;
private EasingFunctionDelegate[] _AnimationFunctions;
private List<AnimationRequest> _AnimationList = new List<AnimationRequest>();
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public Animation(AnimationEasing animationEasing, int animationDuration)
:
this(new AnimationRequest[0], animationEasing, animationDuration)
{
}
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public Animation(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration)
:
this(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration)
{
}
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public Animation(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration)
{
if (animationRequests != null && animationRequests.Length > 0)
_AnimationList.AddRange(animationRequests);
_EasingFunction = animationEasing;
_Duration = (int)animationDuration;
InitializeAnimationFunctions();
}
private void InitializeAnimationFunctions()
{
_AnimationFunctions = new EasingFunctionDelegate[28];
_AnimationFunctions[(int)AnimationEasing.EaseInBounce] = new EasingFunctionDelegate(EaseInBounce);
_AnimationFunctions[(int)AnimationEasing.EaseInCirc] = new EasingFunctionDelegate(EaseInCirc);
_AnimationFunctions[(int)AnimationEasing.EaseInCubic] = new EasingFunctionDelegate(EaseInCubic);
_AnimationFunctions[(int)AnimationEasing.EaseInElastic] = new EasingFunctionDelegate(EaseInElastic);
_AnimationFunctions[(int)AnimationEasing.EaseInExpo] = new EasingFunctionDelegate(EaseInExpo);
_AnimationFunctions[(int)AnimationEasing.EaseInOutBounce] = new EasingFunctionDelegate(EaseInOutBounce);
_AnimationFunctions[(int)AnimationEasing.EaseInOutCirc] = new EasingFunctionDelegate(EaseInOutCirc);
_AnimationFunctions[(int)AnimationEasing.EaseInOutCubic] = new EasingFunctionDelegate(EaseInOutCubic);
_AnimationFunctions[(int)AnimationEasing.EaseInOutElastic] = new EasingFunctionDelegate(EaseInOutElastic);
_AnimationFunctions[(int)AnimationEasing.EaseInOutExpo] = new EasingFunctionDelegate(EaseInOutExpo);
_AnimationFunctions[(int)AnimationEasing.EaseInOutQuad] = new EasingFunctionDelegate(EaseInOutQuad);
_AnimationFunctions[(int)AnimationEasing.EaseInOutQuart] = new EasingFunctionDelegate(EaseInOutQuart);
_AnimationFunctions[(int)AnimationEasing.EaseInOutQuint] = new EasingFunctionDelegate(EaseInOutQuint);
_AnimationFunctions[(int)AnimationEasing.EaseInOutSine] = new EasingFunctionDelegate(EaseInOutSine);
_AnimationFunctions[(int)AnimationEasing.EaseInQuad] = new EasingFunctionDelegate(EaseInQuad);
_AnimationFunctions[(int)AnimationEasing.EaseInQuart] = new EasingFunctionDelegate(EaseInQuart);
_AnimationFunctions[(int)AnimationEasing.EaseInQuint] = new EasingFunctionDelegate(EaseInQuint);
_AnimationFunctions[(int)AnimationEasing.EaseInSine] = new EasingFunctionDelegate(EaseInSine);
_AnimationFunctions[(int)AnimationEasing.EaseOutBounce] = new EasingFunctionDelegate(EaseOutBounce);
_AnimationFunctions[(int)AnimationEasing.EaseOutCirc] = new EasingFunctionDelegate(EaseOutCirc);
_AnimationFunctions[(int)AnimationEasing.EaseOutCubic] = new EasingFunctionDelegate(EaseOutCubic);
_AnimationFunctions[(int)AnimationEasing.EaseOutElastic] = new EasingFunctionDelegate(EaseOutElastic);
_AnimationFunctions[(int)AnimationEasing.EaseOutExpo] = new EasingFunctionDelegate(EaseOutExpo);
_AnimationFunctions[(int)AnimationEasing.EaseOutQuad] = new EasingFunctionDelegate(EaseOutQuad);
_AnimationFunctions[(int)AnimationEasing.EaseOutQuart] = new EasingFunctionDelegate(EaseOutQuart);
_AnimationFunctions[(int)AnimationEasing.EaseOutQuint] = new EasingFunctionDelegate(EaseOutQuint);
_AnimationFunctions[(int)AnimationEasing.EaseOutSine] = new EasingFunctionDelegate(EaseOutSine);
_AnimationFunctions[(int)AnimationEasing.Linear] = new EasingFunctionDelegate(Linear);
}
#endregion
#region Implementation
private bool _AutoDispose = false;
/// <summary>
/// Gets or sets whether animation is auto-disposed once its completed. Default value is false.
/// </summary>
public bool AutoDispose
{
get { return _AutoDispose; }
set
{
_AutoDispose = value;
}
}
public List<AnimationRequest> Animations
{
get
{
return _AnimationList;
}
}
protected override void Dispose(bool disposing)
{
//Console.WriteLine("{0} Animation DISPOSED", DateTime.Now);
Stop();
_IsDisposed = true;
base.Dispose(disposing);
}
private bool _IsDisposed = false;
public bool IsDisposed
{
get { return _IsDisposed; }
internal set
{
_IsDisposed = value;
}
}
/// <summary>
/// Stops animation if one is currently running.
/// </summary>
public void Stop()
{
BackgroundWorker worker = _Worker;
if (worker != null)
{
worker.DoWork -= new DoWorkEventHandler(WorkerDoWork);
worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(RunWorkerCompleted);
worker.CancelAsync();
worker.Dispose();
_Worker = null;
}
}
public void Start()
{
Start(_AnimationList.ToArray());
}
protected void Start(AnimationRequest[] requests)
{
if (_Worker != null)
throw new InvalidOperationException("Animation is already running animations");
//Console.WriteLine("{0} Animation Started", DateTime.Now);
_IsCompleted = false;
_Worker = new BackgroundWorker();
_Worker.WorkerSupportsCancellation = true;
_Worker.DoWork += new DoWorkEventHandler(WorkerDoWork);
_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
_Worker.RunWorkerAsync(requests);
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Console.WriteLine(string.Format("{0} RunWorkerCompleted", DateTime.Now));
BackgroundWorker worker = _Worker;
_Worker = null;
if (worker != null)
{
worker.DoWork -= new DoWorkEventHandler(WorkerDoWork);
worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(RunWorkerCompleted);
worker.Dispose();
}
_IsCompleted = true;
OnAnimationCompleted(EventArgs.Empty);
if (_AutoDispose)
this.Dispose();
}
protected virtual void SetTargetPropertyValue(object target, PropertyInfo property, object value)
{
Control c = target as Control;
if (c != null)
{
c.Invoke(new MethodInvoker(delegate
{
property.SetValue(target, value, null);
if (c.Parent != null)
c.Parent.Update();
else
c.Update();
}));
}
else if (target is BaseItem)
{
if (_AnimationUpdateControl != null)
_AnimationUpdateControl.Invoke(new MethodInvoker(delegate { property.SetValue(target, value, null); if (value is Rectangle) _AnimationUpdateControl.Invalidate(); }));
else
{
if (target is DevComponents.DotNetBar.Metro.MetroTileItem && property.Name == "CurrentFrameOffset")
((DevComponents.DotNetBar.Metro.MetroTileItem)target).CurrentFrameOffset = (int)value;
else
property.SetValue(target, value, null);
}
}
else
{
property.SetValue(target, value, null);
}
}
protected abstract object GetPropertyValueCorrectType(double value);
protected virtual void WorkerDoWork(object sender, DoWorkEventArgs e)
{
AnimationRequest[] requests = (AnimationRequest[])e.Argument;
double elapsedTime = 0;
DateTime startTime = DateTime.UtcNow;
double duration = _Duration;
bool firstPass = true;
if (_FixedStepCount <= 0)
{
while (elapsedTime <= duration)
{
try
{
foreach (AnimationRequest request in requests)
{
double toValue = request.GetToValue();
double fromValue = request.GetFromValue();
double change = toValue - fromValue;
if (firstPass)
SetTargetPropertyValue(request.Target, request.Property, request.From);
double r = _AnimationFunctions[(int)_EasingFunction](elapsedTime, fromValue, change, duration);
if (change < 0 && r < toValue || change > 0 && r > toValue) { r = toValue; e.Cancel = true; break; }
if (change < 0 && r > fromValue || change > 0 && r < fromValue) r = fromValue;
SetTargetPropertyValue(request.Target, request.Property, GetPropertyValueCorrectType(r));
elapsedTime = DateTime.UtcNow.Subtract(startTime).TotalMilliseconds;
if (e.Cancel) break;
}
if (e.Cancel) break;
ExecuteStepUpdateMethod();
if (_AnimationUpdateControl != null)
{
if (_AnimationUpdateControl.InvokeRequired)
_AnimationUpdateControl.BeginInvoke(new MethodInvoker(delegate { _AnimationUpdateControl.Update(); }));
else
_AnimationUpdateControl.Update();
}
if (e.Cancel) break;
firstPass = false;
}
catch (TargetInvocationException exc)
{
if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed
return;
throw;
}
}
}
else
{
try
{
for (int i = 0; i < _FixedStepCount; i++)
{
foreach (AnimationRequest request in requests)
{
double toValue = request.GetToValue();
double fromValue = request.GetFromValue();
double change = toValue - fromValue;
double step = change / _FixedStepCount;
if (firstPass)
SetTargetPropertyValue(request.Target, request.Property, request.From);
double r = fromValue + step * (i + 1);
if (change < 0 && r < toValue || change > 0 && r > toValue) { r = toValue; e.Cancel = true; break; }
if (change < 0 && r > fromValue || change > 0 && r < fromValue) r = fromValue;
SetTargetPropertyValue(request.Target, request.Property, GetPropertyValueCorrectType(r));
if (e.Cancel) break;
if (_Duration > 0)
{
try
{
using (
System.Threading.ManualResetEvent wait =
new System.Threading.ManualResetEvent(false))
wait.WaitOne((int) _Duration);
//System.Threading.Thread.Sleep((int)_Duration);
}
catch
{
break;
}
}
}
if (e.Cancel) break;
ExecuteStepUpdateMethod();
if (_AnimationUpdateControl != null)
_AnimationUpdateControl.Update();
if (e.Cancel) break;
firstPass = false;
}
}
catch (TargetInvocationException exc)
{
if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed
return;
throw;
}
}
// Make sure final to value is assigned
foreach (AnimationRequest request in requests)
{
try
{
SetTargetPropertyValue(request.Target, request.Property, request.To);
}
catch (TargetInvocationException exc)
{
if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed
continue;
throw;
}
}
//System.Diagnostics.Debug.WriteLine(string.Format("{0} WorkerDoWork DONE", DateTime.Now));
}
private bool _IsCompleted;
/// <summary>
/// Gets whether animation run is complete.
/// </summary>
public bool IsCompleted
{
get { return _IsCompleted; }
}
/// <summary>
/// Gets the animation duration in milliseconds.
/// </summary>
public double Duration
{
get { return _Duration; }
internal set
{
_Duration = value;
}
}
/// <summary>
/// Gets the animation easing function.
/// </summary>
public AnimationEasing EasingFunction
{
get
{
return _EasingFunction;
}
}
protected EasingFunctionDelegate[] AnimationFunctions
{
get
{
return _AnimationFunctions;
}
}
protected virtual void ExecuteStepUpdateMethod()
{
if (_StepUpdateMethod != null)
_StepUpdateMethod.DynamicInvoke(null);
}
private Delegate _StepUpdateMethod = null;
/// <summary>
/// Sets the method which is called each time value on target object property is set. This method may execute the visual updates on animation client.
/// </summary>
/// <param name="method">Method to call</param>
public void SetStepUpdateMethod(Delegate method)
{
_StepUpdateMethod = method;
}
protected delegate double EasingFunctionDelegate(double t, double b, double c, double d);
private Control _AnimationUpdateControl;
public Control AnimationUpdateControl
{
get { return _AnimationUpdateControl; }
set { _AnimationUpdateControl = value; }
}
private int _FixedStepCount = 0;
/// <summary>
/// Gets or sets the number of fixed steps animation will perform from star to finish instead of using the easing function in time.
/// Stepped animation executes specified number of steps always with Duration specifying delays between each step.
/// </summary>
public int FixedStepCount
{
get { return _FixedStepCount; }
set
{
_FixedStepCount = value;
}
}
#endregion
#region Easing Functions
private double EaseInOutQuad(double t, double b, double c, double d)
{
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
private double EaseInQuad(double t, double b, double c, double d)
{
return c * (t /= d) * t + b;
}
private double EaseOutQuad(double t, double b, double c, double d)
{
return -c * (t /= d) * (t - 2) + b;
}
private double EaseInCubic(double t, double b, double c, double d)
{
return c * (t /= d) * t * t + b;
}
private double EaseOutCubic(double t, double b, double c, double d)
{
return c * ((t = t / d - 1) * t * t + 1) + b;
}
private double EaseInOutCubic(double t, double b, double c, double d)
{
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
}
private double EaseInQuart(double t, double b, double c, double d)
{
return c * (t /= d) * t * t * t + b;
}
private double EaseOutQuart(double t, double b, double c, double d)
{
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
}
private double EaseInOutQuart(double t, double b, double c, double d)
{
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}
private double EaseInQuint(double t, double b, double c, double d)
{
return c * (t /= d) * t * t * t * t + b;
}
private double EaseOutQuint(double t, double b, double c, double d)
{
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
}
private double EaseInOutQuint(double t, double b, double c, double d)
{
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}
private double EaseInSine(double t, double b, double c, double d)
{
return -c * Math.Cos(t / d * (Math.PI / 2)) + c + b;
}
private double EaseOutSine(double t, double b, double c, double d)
{
return c * Math.Sin(t / d * (Math.PI / 2)) + b;
}
private double EaseInOutSine(double t, double b, double c, double d)
{
return -c / 2 * (Math.Cos(Math.PI * t / d) - 1) + b;
}
private double EaseInExpo(double t, double b, double c, double d)
{
return (t == 0) ? b : c * Math.Pow(2, 10 * (t / d - 1)) + b;
}
private double EaseOutExpo(double t, double b, double c, double d)
{
return (t == d) ? b + c : c * (-Math.Pow(2, -10 * t / d) + 1) + b;
}
private double EaseInOutExpo(double t, double b, double c, double d)
{
if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.Pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.Pow(2, -10 * --t) + 2) + b;
}
private double EaseInCirc(double t, double b, double c, double d)
{
return -c * (Math.Sqrt(1 - (t /= d) * t) - 1) + b;
}
private double EaseOutCirc(double t, double b, double c, double d)
{
return c * Math.Sqrt(1 - (t = t / d - 1) * t) + b;
}
private double EaseInOutCirc(double t, double b, double c, double d)
{
if ((t /= d / 2) < 1) return -c / 2 * (Math.Sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.Sqrt(1 - (t -= 2) * t) + 1) + b;
}
private double EaseInElastic(double t, double b, double c, double d)
{
double s = 1.70158;
double p = 0;
double a = c;
if (t == 0)
return b;
if ((t /= d) == 1)
return b + c;
if (p == 0)
p = d * .3;
if (a < Math.Abs(c))
{
a = c;
s = p / 4;
}
else
s = p / (2 * Math.PI) * Math.Asin(c / a);
return -(a * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b;
}
private double EaseOutElastic(double t, double b, double c, double d)
{
double s = 1.70158;
double p = 0;
double a = c;
if (t == 0)
return b;
if ((t /= d) == 1)
return b + c;
if (p == 0) p = d * .3;
if (a < Math.Abs(c))
{
a = c;
s = p / 4;
}
else
s = p / (2 * Math.PI) * Math.Asin(c / a);
return a * Math.Pow(2, -10 * t) * Math.Sin((t * d - s) * (2 * Math.PI) / p) + c + b;
}
private double EaseInOutElastic(double t, double b, double c, double d)
{
double s = 1.70158;
double p = 0;
double a = c;
if (t == 0)
return b;
if ((t /= d / 2) == 2)
return b + c;
if (p == 0)
p = d * (.3 * 1.5);
if (a < Math.Abs(c))
{
a = c;
s = p / 4;
}
else
s = p / (2 * Math.PI) * Math.Asin(c / a);
if (t < 1)
return -.5 * (a * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.Pow(2, -10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
}
private double EaseInBounce(double t, double b, double c, double d)
{
return c - EaseOutBounce(d - t, 0, c, d) + b;
}
private double EaseOutBounce(double t, double b, double c, double d)
{
if ((t /= d) < (1 / 2.75))
{
return c * (7.5625 * t * t) + b;
}
else if (t < (2 / 2.75))
{
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
}
else if (t < (2.5 / 2.75))
{
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
}
else
{
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
}
private double EaseInOutBounce(double t, double b, double c, double d)
{
if (t < d / 2) return EaseInBounce(t * 2, 0, c, d) * .5 + b;
return EaseOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
private double Linear(double t, double b, double c, double d)
{
return (t / d) * c + b;
}
#endregion
}
internal class AnimationRequest
{
private PropertyInfo _TargetProperty = null;
/// <summary>
/// Initializes a new instance of the AnimationRequest class.
/// </summary>
/// <param name="target">Target object for animation.</param>
/// <param name="targetPropertyName">Target property name for animation.</param>
/// <param name="from">From value.</param>
/// <param name="to">To value.</param>
public AnimationRequest(object target, string targetPropertyName, object to)
{
_TargetProperty = target.GetType().GetProperty(targetPropertyName);
_Target = target;
From = _TargetProperty.GetValue(target, null);
To = to;
}
/// <summary>
/// Initializes a new instance of the AnimationRequest class.
/// </summary>
/// <param name="target">Target object for animation.</param>
/// <param name="targetPropertyName">Target property name for animation.</param>
/// <param name="from">From value.</param>
/// <param name="to">To value.</param>
public AnimationRequest(object target, string targetPropertyName, object from, object to)
{
_TargetProperty = target.GetType().GetProperty(targetPropertyName);
_Target = target;
From = from;
To = to;
}
private object _Target;
/// <summary>
/// Target object for animation.
/// </summary>
public object Target
{
get { return _Target; }
set { _Target = value; }
}
private object _From;
/// <summary>
/// Animation from value.
/// </summary>
public object From
{
get { return _From; }
set
{
_From = value;
_FromValue = GetDoubleValue(value);
}
}
private object _To;
/// <summary>
/// Animation to value.
/// </summary>
public object To
{
get { return _To; }
set
{
_To = value;
_ToValue = GetDoubleValue(value);
}
}
private static double GetDoubleValue(object value)
{
if (value is int)
return (double)(int)value;
else if (value is double)
return (double)value;
else if (value is long)
return (double)(long)value;
else if (value is float)
return (double)(float)value;
return double.NaN;
}
internal PropertyInfo Property
{
get
{
return _TargetProperty;
}
}
private double _ToValue = double.NaN;
internal double GetToValue()
{
return _ToValue;
}
private double _FromValue = double.NaN;
internal double GetFromValue()
{
return _FromValue;
}
}
/// <summary>
/// Specifies the animation easing function
/// </summary>
public enum AnimationEasing : int
{
EaseInOutQuad = 0,
EaseInQuad = 1,
EaseOutQuad = 2,
EaseInCubic = 3,
EaseOutCubic = 4,
EaseInOutCubic = 5,
EaseInQuart = 6,
EaseOutQuart = 7,
EaseInOutQuart = 8,
EaseInQuint = 9,
EaseOutQuint = 10,
EaseInOutQuint = 11,
EaseInSine = 12,
EaseOutSine = 13,
EaseInOutSine = 14,
EaseInExpo = 15,
EaseOutExpo = 16,
EaseInOutExpo = 17,
EaseInCirc = 18,
EaseOutCirc = 19,
EaseInOutCirc = 20,
EaseInElastic = 21,
EaseOutElastic = 22,
EaseInOutElastic = 23,
EaseInBounce = 24,
EaseOutBounce = 25,
EaseInOutBounce = 26,
Linear = 27
}
}

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.DotNetBar.Animation
{
internal class AnimationDouble : Animation
{
#region Constructor
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public AnimationDouble(AnimationEasing animationEasing, int animationDuration)
:
base(new AnimationRequest[0], animationEasing, animationDuration)
{
}
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public AnimationDouble(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration)
:
base(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration)
{
}
/// <summary>
/// Initializes a new instance of the Animation class.
/// </summary>
/// <param name="target">Target object for animation</param>
/// <param name="targetPropertyName">Target property name for animation</param>
public AnimationDouble(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration)
:
base(animationRequests, animationEasing, animationDuration) { }
#endregion
protected override object GetPropertyValueCorrectType(double value)
{
return value;
}
}
}

Some files were not shown because too many files have changed in this diff Show More