diff --git a/data/layout.xml b/data/layout.xml
index 479c14e..61340cb 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -1,7 +1,7 @@
-
+
@@ -19,12 +19,12 @@
-
+
-
+
@@ -38,33 +38,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
@@ -72,11 +118,14 @@
-
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
-
-
+
@@ -145,5 +217,6 @@
+
diff --git a/data/spritesheet.png b/data/spritesheet.png
new file mode 100644
index 0000000..a92c234
Binary files /dev/null and b/data/spritesheet.png differ
diff --git a/data/spritesheet.txt b/data/spritesheet.txt
new file mode 100644
index 0000000..ff5cd41
--- /dev/null
+++ b/data/spritesheet.txt
@@ -0,0 +1,1006 @@
+accept 16 16 5 5
+add 16 16 31 5
+anchor 16 16 57 5
+application 16 16 83 5
+application_add 16 16 109 5
+application_cascade 16 16 135 5
+application_delete 16 16 161 5
+application_double 16 16 187 5
+application_edit 16 16 213 5
+application_error 16 16 239 5
+application_form 16 16 265 5
+application_form_add 16 16 291 5
+application_form_delete 16 16 317 5
+application_form_edit 16 16 343 5
+application_form_magnify 16 16 369 5
+application_get 16 16 395 5
+application_go 16 16 421 5
+application_home 16 16 447 5
+application_key 16 16 473 5
+application_lightning 16 16 499 5
+application_link 16 16 525 5
+application_osx 16 16 551 5
+application_osx_terminal 16 16 577 5
+application_put 16 16 603 5
+application_side_boxes 16 16 629 5
+application_side_contract 16 16 655 5
+application_side_expand 16 16 681 5
+application_side_list 16 16 707 5
+application_side_tree 16 16 733 5
+application_split 16 16 759 5
+application_tile_horizontal 16 16 785 5
+application_tile_vertical 16 16 5 31
+application_view_columns 16 16 31 31
+application_view_detail 16 16 57 31
+application_view_gallery 16 16 83 31
+application_view_icons 16 16 109 31
+application_view_list 16 16 135 31
+application_view_tile 16 16 161 31
+application_xp 16 16 187 31
+application_xp_terminal 16 16 213 31
+arrow_branch 16 16 239 31
+arrow_divide 16 16 265 31
+arrow_down 16 16 291 31
+arrow_in 16 16 317 31
+arrow_inout 16 16 343 31
+arrow_join 16 16 369 31
+arrow_left 16 16 395 31
+arrow_merge 16 16 421 31
+arrow_out 16 16 447 31
+arrow_redo 16 16 473 31
+arrow_refresh 16 16 499 31
+arrow_refresh_small 16 16 525 31
+arrow_right 16 16 551 31
+arrow_rotate_anticlockwise 16 16 577 31
+arrow_rotate_clockwise 16 16 603 31
+arrow_switch 16 16 629 31
+arrow_turn_left 16 16 655 31
+arrow_turn_right 16 16 681 31
+arrow_undo 16 16 707 31
+arrow_up 16 16 733 31
+asterisk_orange 16 16 759 31
+asterisk_yellow 16 16 785 31
+attach 16 16 5 57
+award_star_add 16 16 31 57
+award_star_bronze_1 16 16 57 57
+award_star_bronze_2 16 16 83 57
+award_star_bronze_3 16 16 109 57
+award_star_delete 16 16 135 57
+award_star_gold_1 16 16 161 57
+award_star_gold_2 16 16 187 57
+award_star_gold_3 16 16 213 57
+award_star_silver_1 16 16 239 57
+award_star_silver_2 16 16 265 57
+award_star_silver_3 16 16 291 57
+basket 16 16 317 57
+basket_add 16 16 343 57
+basket_delete 16 16 369 57
+basket_edit 16 16 395 57
+basket_error 16 16 421 57
+basket_go 16 16 447 57
+basket_put 16 16 473 57
+basket_remove 16 16 499 57
+bell 16 16 525 57
+bell_add 16 16 551 57
+bell_delete 16 16 577 57
+bell_error 16 16 603 57
+bell_go 16 16 629 57
+bell_link 16 16 655 57
+bin 16 16 681 57
+bin_closed 16 16 707 57
+bin_empty 16 16 733 57
+bomb 16 16 759 57
+book 16 16 785 57
+book_add 16 16 5 83
+book_addresses 16 16 31 83
+book_delete 16 16 57 83
+book_edit 16 16 83 83
+book_error 16 16 109 83
+book_go 16 16 135 83
+book_key 16 16 161 83
+book_link 16 16 187 83
+book_next 16 16 213 83
+book_open 16 16 239 83
+book_previous 16 16 265 83
+box 16 16 291 83
+brick 16 16 317 83
+brick_add 16 16 343 83
+brick_delete 16 16 369 83
+brick_edit 16 16 395 83
+brick_error 16 16 421 83
+brick_go 16 16 447 83
+brick_link 16 16 473 83
+bricks 16 16 499 83
+briefcase 16 16 525 83
+bug 16 16 551 83
+bug_add 16 16 577 83
+bug_delete 16 16 603 83
+bug_edit 16 16 629 83
+bug_error 16 16 655 83
+bug_go 16 16 681 83
+bug_link 16 16 707 83
+building 16 16 733 83
+building_add 16 16 759 83
+building_delete 16 16 785 83
+building_edit 16 16 5 109
+building_error 16 16 31 109
+building_go 16 16 57 109
+building_key 16 16 83 109
+building_link 16 16 109 109
+bullet_add 16 16 135 109
+bullet_arrow_bottom 16 16 161 109
+bullet_arrow_down 16 16 187 109
+bullet_arrow_top 16 16 213 109
+bullet_arrow_up 16 16 239 109
+bullet_black 16 16 265 109
+bullet_blue 16 16 291 109
+bullet_delete 16 16 317 109
+bullet_disk 16 16 343 109
+bullet_error 16 16 369 109
+bullet_feed 16 16 395 109
+bullet_go 16 16 421 109
+bullet_green 16 16 447 109
+bullet_key 16 16 473 109
+bullet_orange 16 16 499 109
+bullet_picture 16 16 525 109
+bullet_pink 16 16 551 109
+bullet_purple 16 16 577 109
+bullet_red 16 16 603 109
+bullet_star 16 16 629 109
+bullet_toggle_minus 16 16 655 109
+bullet_toggle_plus 16 16 681 109
+bullet_white 16 16 707 109
+bullet_wrench 16 16 733 109
+bullet_yellow 16 16 759 109
+cake 16 16 785 109
+calculator 16 16 5 135
+calculator_add 16 16 31 135
+calculator_delete 16 16 57 135
+calculator_edit 16 16 83 135
+calculator_error 16 16 109 135
+calculator_link 16 16 135 135
+calendar 16 16 161 135
+calendar_add 16 16 187 135
+calendar_delete 16 16 213 135
+calendar_edit 16 16 239 135
+calendar_link 16 16 265 135
+calendar_view_day 16 16 291 135
+calendar_view_month 16 16 317 135
+calendar_view_week 16 16 343 135
+camera 16 16 369 135
+camera_add 16 16 395 135
+camera_delete 16 16 421 135
+camera_edit 16 16 447 135
+camera_error 16 16 473 135
+camera_go 16 16 499 135
+camera_link 16 16 525 135
+camera_small 16 16 551 135
+cancel 16 16 577 135
+car 16 16 603 135
+car_add 16 16 629 135
+car_delete 16 16 655 135
+cart 16 16 681 135
+cart_add 16 16 707 135
+cart_delete 16 16 733 135
+cart_edit 16 16 759 135
+cart_error 16 16 785 135
+cart_go 16 16 5 161
+cart_put 16 16 31 161
+cart_remove 16 16 57 161
+cd 16 16 83 161
+cd_add 16 16 109 161
+cd_burn 16 16 135 161
+cd_delete 16 16 161 161
+cd_edit 16 16 187 161
+cd_eject 16 16 213 161
+cd_go 16 16 239 161
+chart_bar 16 16 265 161
+chart_bar_add 16 16 291 161
+chart_bar_delete 16 16 317 161
+chart_bar_edit 16 16 343 161
+chart_bar_error 16 16 369 161
+chart_bar_link 16 16 395 161
+chart_curve 16 16 421 161
+chart_curve_add 16 16 447 161
+chart_curve_delete 16 16 473 161
+chart_curve_edit 16 16 499 161
+chart_curve_error 16 16 525 161
+chart_curve_go 16 16 551 161
+chart_curve_link 16 16 577 161
+chart_line 16 16 603 161
+chart_line_add 16 16 629 161
+chart_line_delete 16 16 655 161
+chart_line_edit 16 16 681 161
+chart_line_error 16 16 707 161
+chart_line_link 16 16 733 161
+chart_organisation 16 16 759 161
+chart_organisation_add 16 16 785 161
+chart_organisation_delete 16 16 5 187
+chart_pie 16 16 31 187
+chart_pie_add 16 16 57 187
+chart_pie_delete 16 16 83 187
+chart_pie_edit 16 16 109 187
+chart_pie_error 16 16 135 187
+chart_pie_link 16 16 161 187
+clock 16 16 187 187
+clock_add 16 16 213 187
+clock_delete 16 16 239 187
+clock_edit 16 16 265 187
+clock_error 16 16 291 187
+clock_go 16 16 317 187
+clock_link 16 16 343 187
+clock_pause 16 16 369 187
+clock_play 16 16 395 187
+clock_red 16 16 421 187
+clock_stop 16 16 447 187
+cog 16 16 473 187
+cog_add 16 16 499 187
+cog_delete 16 16 525 187
+cog_edit 16 16 551 187
+cog_error 16 16 577 187
+cog_go 16 16 603 187
+coins 16 16 629 187
+coins_add 16 16 655 187
+coins_delete 16 16 681 187
+color_swatch 16 16 707 187
+color_wheel 16 16 733 187
+comment 16 16 759 187
+comment_add 16 16 785 187
+comment_delete 16 16 5 213
+comment_edit 16 16 31 213
+comments 16 16 57 213
+comments_add 16 16 83 213
+comments_delete 16 16 109 213
+compress 16 16 135 213
+computer 16 16 161 213
+computer_add 16 16 187 213
+computer_delete 16 16 213 213
+computer_edit 16 16 239 213
+computer_error 16 16 265 213
+computer_go 16 16 291 213
+computer_key 16 16 317 213
+computer_link 16 16 343 213
+connect 16 16 369 213
+contrast 16 16 395 213
+contrast_decrease 16 16 421 213
+contrast_high 16 16 447 213
+contrast_increase 16 16 473 213
+contrast_low 16 16 499 213
+control_eject 16 16 525 213
+control_eject_blue 16 16 551 213
+control_end 16 16 577 213
+control_end_blue 16 16 603 213
+control_equalizer 16 16 629 213
+control_equalizer_blue 16 16 655 213
+control_fastforward 16 16 681 213
+control_fastforward_blue 16 16 707 213
+control_pause 16 16 733 213
+control_pause_blue 16 16 759 213
+control_play 16 16 785 213
+control_play_blue 16 16 5 239
+control_repeat 16 16 31 239
+control_repeat_blue 16 16 57 239
+control_rewind 16 16 83 239
+control_rewind_blue 16 16 109 239
+control_start 16 16 135 239
+control_start_blue 16 16 161 239
+control_stop 16 16 187 239
+control_stop_blue 16 16 213 239
+controller 16 16 239 239
+controller_add 16 16 265 239
+controller_delete 16 16 291 239
+controller_error 16 16 317 239
+creditcards 16 16 343 239
+cross 16 16 369 239
+css 16 16 395 239
+css_add 16 16 421 239
+css_delete 16 16 447 239
+css_go 16 16 473 239
+css_valid 16 16 499 239
+cup 16 16 525 239
+cup_add 16 16 551 239
+cup_delete 16 16 577 239
+cup_edit 16 16 603 239
+cup_error 16 16 629 239
+cup_go 16 16 655 239
+cup_key 16 16 681 239
+cup_link 16 16 707 239
+cursor 16 16 733 239
+cut 16 16 759 239
+cut_red 16 16 785 239
+database 16 16 5 265
+database_add 16 16 31 265
+database_connect 16 16 57 265
+database_delete 16 16 83 265
+database_edit 16 16 109 265
+database_error 16 16 135 265
+database_gear 16 16 161 265
+database_go 16 16 187 265
+database_key 16 16 213 265
+database_lightning 16 16 239 265
+database_link 16 16 265 265
+database_refresh 16 16 291 265
+database_save 16 16 317 265
+database_table 16 16 343 265
+date 16 16 369 265
+date_add 16 16 395 265
+date_delete 16 16 421 265
+date_edit 16 16 447 265
+date_error 16 16 473 265
+date_go 16 16 499 265
+date_link 16 16 525 265
+date_magnify 16 16 551 265
+date_next 16 16 577 265
+date_previous 16 16 603 265
+delete 16 16 629 265
+disconnect 16 16 655 265
+disk 16 16 681 265
+disk_multiple 16 16 707 265
+door 16 16 733 265
+door_in 16 16 759 265
+door_open 16 16 785 265
+door_out 16 16 5 291
+drink 16 16 31 291
+drink_empty 16 16 57 291
+drive 16 16 83 291
+drive_add 16 16 109 291
+drive_burn 16 16 135 291
+drive_cd 16 16 161 291
+drive_cd_empty 16 16 187 291
+drive_delete 16 16 213 291
+drive_disk 16 16 239 291
+drive_edit 16 16 265 291
+drive_error 16 16 291 291
+drive_go 16 16 317 291
+drive_key 16 16 343 291
+drive_link 16 16 369 291
+drive_magnify 16 16 395 291
+drive_network 16 16 421 291
+drive_rename 16 16 447 291
+drive_user 16 16 473 291
+drive_web 16 16 499 291
+dvd 16 16 525 291
+dvd_add 16 16 551 291
+dvd_delete 16 16 577 291
+dvd_edit 16 16 603 291
+dvd_error 16 16 629 291
+dvd_go 16 16 655 291
+dvd_key 16 16 681 291
+dvd_link 16 16 707 291
+email 16 16 733 291
+email_add 16 16 759 291
+email_attach 16 16 785 291
+email_delete 16 16 5 317
+email_edit 16 16 31 317
+email_error 16 16 57 317
+email_go 16 16 83 317
+email_link 16 16 109 317
+email_open 16 16 135 317
+email_open_image 16 16 161 317
+emoticon_evilgrin 16 16 187 317
+emoticon_grin 16 16 213 317
+emoticon_happy 16 16 239 317
+emoticon_smile 16 16 265 317
+emoticon_surprised 16 16 291 317
+emoticon_tongue 16 16 317 317
+emoticon_unhappy 16 16 343 317
+emoticon_waii 16 16 369 317
+emoticon_wink 16 16 395 317
+error 16 16 421 317
+error_add 16 16 447 317
+error_delete 16 16 473 317
+error_go 16 16 499 317
+exclamation 16 16 525 317
+eye 16 16 551 317
+feed 16 16 577 317
+feed_add 16 16 603 317
+feed_delete 16 16 629 317
+feed_disk 16 16 655 317
+feed_edit 16 16 681 317
+feed_error 16 16 707 317
+feed_go 16 16 733 317
+feed_key 16 16 759 317
+feed_link 16 16 785 317
+feed_magnify 16 16 5 343
+female 16 16 31 343
+film 16 16 57 343
+film_add 16 16 83 343
+film_delete 16 16 109 343
+film_edit 16 16 135 343
+film_error 16 16 161 343
+film_go 16 16 187 343
+film_key 16 16 213 343
+film_link 16 16 239 343
+film_save 16 16 265 343
+find 16 16 291 343
+flag_blue 16 16 317 343
+flag_green 16 16 343 343
+flag_orange 16 16 369 343
+flag_pink 16 16 395 343
+flag_purple 16 16 421 343
+flag_red 16 16 447 343
+flag_yellow 16 16 473 343
+folder 16 16 499 343
+folder_add 16 16 525 343
+folder_bell 16 16 551 343
+folder_brick 16 16 577 343
+folder_bug 16 16 603 343
+folder_camera 16 16 629 343
+folder_database 16 16 655 343
+folder_delete 16 16 681 343
+folder_edit 16 16 707 343
+folder_error 16 16 733 343
+folder_explore 16 16 759 343
+folder_feed 16 16 785 343
+folder_find 16 16 5 369
+folder_go 16 16 31 369
+folder_heart 16 16 57 369
+folder_image 16 16 83 369
+folder_key 16 16 109 369
+folder_lightbulb 16 16 135 369
+folder_link 16 16 161 369
+folder_magnify 16 16 187 369
+folder_page 16 16 213 369
+folder_page_white 16 16 239 369
+folder_palette 16 16 265 369
+folder_picture 16 16 291 369
+folder_star 16 16 317 369
+folder_table 16 16 343 369
+folder_user 16 16 369 369
+folder_wrench 16 16 395 369
+font 16 16 421 369
+font_add 16 16 447 369
+font_delete 16 16 473 369
+font_go 16 16 499 369
+github 30 30 525 369
+gmail 30 30 565 369
+group 16 16 605 369
+group_add 16 16 631 369
+group_delete 16 16 657 369
+group_edit 16 16 683 369
+group_error 16 16 709 369
+group_gear 16 16 735 369
+group_go 16 16 761 369
+group_key 16 16 787 369
+group_link 16 16 5 395
+heart 16 16 31 395
+heart_add 16 16 57 395
+heart_delete 16 16 83 395
+help 16 16 109 395
+hourglass 16 16 135 395
+hourglass_add 16 16 161 395
+hourglass_delete 16 16 187 395
+hourglass_go 16 16 213 395
+hourglass_link 16 16 239 395
+house 16 16 265 395
+house_go 16 16 291 395
+house_link 16 16 317 395
+html 16 16 343 395
+html_add 16 16 369 395
+html_delete 16 16 395 395
+html_go 16 16 421 395
+html_valid 16 16 447 395
+image 16 16 473 395
+image_add 16 16 499 395
+image_delete 16 16 605 395
+image_edit 16 16 631 395
+image_link 16 16 657 395
+images 16 16 683 395
+information 16 16 709 395
+ipod 16 16 735 395
+ipod_cast 16 16 761 395
+ipod_cast_add 16 16 787 395
+ipod_cast_delete 16 16 5 421
+ipod_sound 16 16 31 421
+joystick 16 16 57 421
+joystick_add 16 16 83 421
+joystick_delete 16 16 109 421
+joystick_error 16 16 135 421
+key 16 16 161 421
+key_add 16 16 187 421
+key_delete 16 16 213 421
+key_go 16 16 239 421
+keyboard 16 16 265 421
+keyboard_add 16 16 291 421
+keyboard_delete 16 16 317 421
+keyboard_magnify 16 16 343 421
+layers 16 16 369 421
+layout 16 16 395 421
+layout_add 16 16 421 421
+layout_content 16 16 447 421
+layout_delete 16 16 473 421
+layout_edit 16 16 499 421
+layout_error 16 16 525 421
+layout_header 16 16 551 421
+layout_link 16 16 577 421
+layout_sidebar 16 16 603 421
+lightbulb 16 16 629 421
+lightbulb_add 16 16 655 421
+lightbulb_delete 16 16 681 421
+lightbulb_off 16 16 707 421
+lightning 16 16 733 421
+lightning_add 16 16 759 421
+lightning_delete 16 16 785 421
+lightning_go 16 16 5 447
+link 16 16 31 447
+link_add 16 16 57 447
+link_break 16 16 83 447
+link_delete 16 16 109 447
+link_edit 16 16 135 447
+link_error 16 16 161 447
+link_go 16 16 187 447
+linkedin 30 30 213 447
+lock 16 16 253 447
+lock_add 16 16 279 447
+lock_break 16 16 305 447
+lock_delete 16 16 331 447
+lock_edit 16 16 357 447
+lock_go 16 16 383 447
+lock_open 16 16 409 447
+lorry 16 16 435 447
+lorry_add 16 16 461 447
+lorry_delete 16 16 487 447
+lorry_error 16 16 513 447
+lorry_flatbed 16 16 539 447
+lorry_go 16 16 565 447
+lorry_link 16 16 591 447
+magifier_zoom_out 16 16 617 447
+magnifier 16 16 643 447
+magnifier_zoom_in 16 16 669 447
+male 16 16 695 447
+map 16 16 721 447
+map_add 16 16 747 447
+map_delete 16 16 773 447
+map_edit 16 16 799 447
+map_go 16 16 5 473
+map_magnify 16 16 31 473
+medal_bronze_1 16 16 57 473
+medal_bronze_2 16 16 83 473
+medal_bronze_3 16 16 109 473
+medal_bronze_add 16 16 135 473
+medal_bronze_delete 16 16 161 473
+medal_gold_1 16 16 187 473
+medal_gold_2 16 16 253 473
+medal_gold_3 16 16 279 473
+medal_gold_add 16 16 305 473
+medal_gold_delete 16 16 331 473
+medal_silver_1 16 16 357 473
+medal_silver_2 16 16 383 473
+medal_silver_3 16 16 409 473
+medal_silver_add 16 16 435 473
+medal_silver_delete 16 16 461 473
+money 16 16 487 473
+money_add 16 16 513 473
+money_delete 16 16 539 473
+money_dollar 16 16 565 473
+money_euro 16 16 591 473
+money_pound 16 16 617 473
+money_yen 16 16 643 473
+monitor 16 16 669 473
+monitor_add 16 16 695 473
+monitor_delete 16 16 721 473
+monitor_edit 16 16 747 473
+monitor_error 16 16 773 473
+monitor_go 16 16 799 473
+monitor_lightning 16 16 5 499
+monitor_link 16 16 31 499
+mouse 16 16 57 499
+mouse_add 16 16 83 499
+mouse_delete 16 16 109 499
+mouse_error 16 16 135 499
+music 16 16 161 499
+new 16 16 187 499
+newspaper 16 16 213 499
+newspaper_add 16 16 239 499
+newspaper_delete 16 16 265 499
+newspaper_go 16 16 291 499
+newspaper_link 16 16 317 499
+note 16 16 343 499
+note_add 16 16 369 499
+note_delete 16 16 395 499
+note_edit 16 16 421 499
+note_error 16 16 447 499
+note_go 16 16 473 499
+overlays 16 16 499 499
+package 16 16 525 499
+package_add 16 16 551 499
+package_delete 16 16 577 499
+package_go 16 16 603 499
+package_green 16 16 629 499
+package_link 16 16 655 499
+page 16 16 681 499
+page_add 16 16 707 499
+page_attach 16 16 733 499
+page_code 16 16 759 499
+page_copy 16 16 785 499
+page_delete 16 16 5 525
+page_edit 16 16 31 525
+page_error 16 16 57 525
+page_excel 16 16 83 525
+page_find 16 16 109 525
+page_gear 16 16 135 525
+page_go 16 16 161 525
+page_green 16 16 187 525
+page_key 16 16 213 525
+page_lightning 16 16 239 525
+page_link 16 16 265 525
+page_paintbrush 16 16 291 525
+page_paste 16 16 317 525
+page_red 16 16 343 525
+page_refresh 16 16 369 525
+page_save 16 16 395 525
+page_white 16 16 421 525
+page_white_acrobat 16 16 447 525
+page_white_actionscript 16 16 473 525
+page_white_add 16 16 499 525
+page_white_c 16 16 525 525
+page_white_camera 16 16 551 525
+page_white_cd 16 16 577 525
+page_white_code 16 16 603 525
+page_white_code_red 16 16 629 525
+page_white_coldfusion 16 16 655 525
+page_white_compressed 16 16 681 525
+page_white_copy 16 16 707 525
+page_white_cplusplus 16 16 733 525
+page_white_csharp 16 16 759 525
+page_white_cup 16 16 785 525
+page_white_database 16 16 5 551
+page_white_delete 16 16 31 551
+page_white_dvd 16 16 57 551
+page_white_edit 16 16 83 551
+page_white_error 16 16 109 551
+page_white_excel 16 16 135 551
+page_white_find 16 16 161 551
+page_white_flash 16 16 187 551
+page_white_freehand 16 16 213 551
+page_white_gear 16 16 239 551
+page_white_get 16 16 265 551
+page_white_go 16 16 291 551
+page_white_h 16 16 317 551
+page_white_horizontal 16 16 343 551
+page_white_key 16 16 369 551
+page_white_lightning 16 16 395 551
+page_white_link 16 16 421 551
+page_white_magnify 16 16 447 551
+page_white_medal 16 16 473 551
+page_white_office 16 16 499 551
+page_white_paint 16 16 525 551
+page_white_paintbrush 16 16 551 551
+page_white_paste 16 16 577 551
+page_white_php 16 16 603 551
+page_white_picture 16 16 629 551
+page_white_powerpoint 16 16 655 551
+page_white_put 16 16 681 551
+page_white_ruby 16 16 707 551
+page_white_stack 16 16 733 551
+page_white_star 16 16 759 551
+page_white_swoosh 16 16 785 551
+page_white_text 16 16 5 577
+page_white_text_width 16 16 31 577
+page_white_tux 16 16 57 577
+page_white_vector 16 16 83 577
+page_white_visualstudio 16 16 109 577
+page_white_width 16 16 135 577
+page_white_word 16 16 161 577
+page_white_world 16 16 187 577
+page_white_wrench 16 16 213 577
+page_white_zip 16 16 239 577
+page_word 16 16 265 577
+page_world 16 16 291 577
+paintbrush 16 16 317 577
+paintcan 16 16 343 577
+palette 16 16 369 577
+paste_plain 16 16 395 577
+paste_word 16 16 421 577
+pencil 16 16 447 577
+pencil_add 16 16 473 577
+pencil_delete 16 16 499 577
+pencil_go 16 16 525 577
+phone 16 16 551 577
+phone_add 16 16 577 577
+phone_delete 16 16 603 577
+phone_sound 16 16 629 577
+photo 16 16 655 577
+photo_add 16 16 681 577
+photo_delete 16 16 707 577
+photo_link 16 16 733 577
+photos 16 16 759 577
+picture 16 16 785 577
+picture_add 16 16 5 603
+picture_delete 16 16 31 603
+picture_edit 16 16 57 603
+picture_empty 16 16 83 603
+picture_error 16 16 109 603
+picture_go 16 16 135 603
+picture_key 16 16 161 603
+picture_link 16 16 187 603
+picture_save 16 16 213 603
+pictures 16 16 239 603
+pilcrow 16 16 265 603
+pill 16 16 291 603
+pill_add 16 16 317 603
+pill_delete 16 16 343 603
+pill_go 16 16 369 603
+plugin 16 16 395 603
+plugin_add 16 16 421 603
+plugin_delete 16 16 447 603
+plugin_disabled 16 16 473 603
+plugin_edit 16 16 499 603
+plugin_error 16 16 525 603
+plugin_go 16 16 551 603
+plugin_link 16 16 577 603
+printer 16 16 603 603
+printer_add 16 16 629 603
+printer_delete 16 16 655 603
+printer_empty 16 16 681 603
+printer_error 16 16 707 603
+rainbow 16 16 733 603
+report 16 16 759 603
+report_add 16 16 785 603
+report_delete 16 16 5 629
+report_disk 16 16 31 629
+report_edit 16 16 57 629
+report_go 16 16 83 629
+report_key 16 16 109 629
+report_link 16 16 135 629
+report_magnify 16 16 161 629
+report_picture 16 16 187 629
+report_user 16 16 213 629
+report_word 16 16 239 629
+resultset_first 16 16 265 629
+resultset_last 16 16 291 629
+resultset_next 16 16 317 629
+resultset_previous 16 16 343 629
+rosette 16 16 369 629
+rss 16 16 395 629
+rss_add 16 16 421 629
+rss_delete 16 16 447 629
+rss_go 16 16 473 629
+rss_valid 16 16 499 629
+ruby 16 16 525 629
+ruby_add 16 16 551 629
+ruby_delete 16 16 577 629
+ruby_gear 16 16 603 629
+ruby_get 16 16 629 629
+ruby_go 16 16 655 629
+ruby_key 16 16 681 629
+ruby_link 16 16 707 629
+ruby_put 16 16 733 629
+script 16 16 759 629
+script_add 16 16 785 629
+script_code 16 16 5 655
+script_code_red 16 16 31 655
+script_delete 16 16 57 655
+script_edit 16 16 83 655
+script_error 16 16 109 655
+script_gear 16 16 135 655
+script_go 16 16 161 655
+script_key 16 16 187 655
+script_lightning 16 16 213 655
+script_link 16 16 239 655
+script_palette 16 16 265 655
+script_save 16 16 291 655
+server 16 16 317 655
+server_add 16 16 343 655
+server_chart 16 16 369 655
+server_compressed 16 16 395 655
+server_connect 16 16 421 655
+server_database 16 16 447 655
+server_delete 16 16 473 655
+server_edit 16 16 499 655
+server_error 16 16 525 655
+server_go 16 16 551 655
+server_key 16 16 577 655
+server_lightning 16 16 603 655
+server_link 16 16 629 655
+server_uncompressed 16 16 655 655
+shading 16 16 681 655
+shape_align_bottom 16 16 707 655
+shape_align_center 16 16 733 655
+shape_align_left 16 16 759 655
+shape_align_middle 16 16 785 655
+shape_align_right 16 16 5 681
+shape_align_top 16 16 31 681
+shape_flip_horizontal 16 16 57 681
+shape_flip_vertical 16 16 83 681
+shape_group 16 16 109 681
+shape_handles 16 16 135 681
+shape_move_back 16 16 161 681
+shape_move_backwards 16 16 187 681
+shape_move_forwards 16 16 213 681
+shape_move_front 16 16 239 681
+shape_rotate_anticlockwise 16 16 265 681
+shape_rotate_clockwise 16 16 291 681
+shape_square 16 16 317 681
+shape_square_add 16 16 343 681
+shape_square_delete 16 16 369 681
+shape_square_edit 16 16 395 681
+shape_square_error 16 16 421 681
+shape_square_go 16 16 447 681
+shape_square_key 16 16 473 681
+shape_square_link 16 16 499 681
+shape_ungroup 16 16 525 681
+shield 16 16 551 681
+shield_add 16 16 577 681
+shield_delete 16 16 603 681
+shield_go 16 16 629 681
+sitemap 16 16 655 681
+sitemap_color 16 16 681 681
+sound 16 16 707 681
+sound_add 16 16 733 681
+sound_delete 16 16 759 681
+sound_low 16 16 785 681
+sound_mute 16 16 5 707
+sound_none 16 16 31 707
+spellcheck 16 16 57 707
+sport_8ball 16 16 83 707
+sport_basketball 16 16 109 707
+sport_football 16 16 135 707
+sport_golf 16 16 161 707
+sport_raquet 16 16 187 707
+sport_shuttlecock 16 16 213 707
+sport_soccer 16 16 239 707
+sport_tennis 16 16 265 707
+stackoverflow 30 30 291 707
+star 16 16 331 707
+status_away 16 16 357 707
+status_busy 16 16 383 707
+status_offline 16 16 409 707
+status_online 16 16 435 707
+stop 16 16 461 707
+style 16 16 487 707
+style_add 16 16 513 707
+style_delete 16 16 539 707
+style_edit 16 16 565 707
+style_go 16 16 591 707
+sum 16 16 617 707
+tab 16 16 643 707
+tab_add 16 16 669 707
+tab_delete 16 16 695 707
+tab_edit 16 16 721 707
+tab_go 16 16 747 707
+table 16 16 773 707
+table_add 16 16 799 707
+table_delete 16 16 5 733
+table_edit 16 16 31 733
+table_error 16 16 57 733
+table_gear 16 16 83 733
+table_go 16 16 109 733
+table_key 16 16 135 733
+table_lightning 16 16 161 733
+table_link 16 16 187 733
+table_multiple 16 16 213 733
+table_refresh 16 16 239 733
+table_relationship 16 16 265 733
+table_row_delete 16 16 331 733
+table_row_insert 16 16 357 733
+table_save 16 16 383 733
+table_sort 16 16 409 733
+tag 16 16 435 733
+tag_blue 16 16 461 733
+tag_blue_add 16 16 487 733
+tag_blue_delete 16 16 513 733
+tag_blue_edit 16 16 539 733
+tag_green 16 16 565 733
+tag_orange 16 16 591 733
+tag_pink 16 16 617 733
+tag_purple 16 16 643 733
+tag_red 16 16 669 733
+tag_yellow 16 16 695 733
+telephone 16 16 721 733
+telephone_add 16 16 747 733
+telephone_delete 16 16 773 733
+telephone_edit 16 16 799 733
+telephone_error 16 16 5 759
+telephone_go 16 16 31 759
+telephone_key 16 16 57 759
+telephone_link 16 16 83 759
+television 16 16 109 759
+television_add 16 16 135 759
+television_delete 16 16 161 759
+text_align_center 16 16 187 759
+text_align_justify 16 16 213 759
+text_align_left 16 16 239 759
+text_align_right 16 16 265 759
+text_allcaps 16 16 291 759
+text_bold 16 16 317 759
+text_columns 16 16 343 759
+text_dropcaps 16 16 369 759
+text_heading_1 16 16 395 759
+text_heading_2 16 16 421 759
+text_heading_3 16 16 447 759
+text_heading_4 16 16 473 759
+text_heading_5 16 16 499 759
+text_heading_6 16 16 525 759
+text_horizontalrule 16 16 551 759
+text_indent 16 16 577 759
+text_indent_remove 16 16 603 759
+text_italic 16 16 629 759
+text_kerning 16 16 655 759
+text_letter_omega 16 16 681 759
+text_letterspacing 16 16 707 759
+text_linespacing 16 16 733 759
+text_list_bullets 16 16 759 759
+text_list_numbers 16 16 785 759
+text_lowercase 16 16 5 785
+text_padding_bottom 16 16 31 785
+text_padding_left 16 16 57 785
+text_padding_right 16 16 83 785
+text_padding_top 16 16 109 785
+text_replace 16 16 135 785
+text_signature 16 16 161 785
+text_smallcaps 16 16 187 785
+text_strikethrough 16 16 213 785
+text_subscript 16 16 239 785
+text_superscript 16 16 265 785
+text_underline 16 16 291 785
+text_uppercase 16 16 317 785
+textfield 16 16 343 785
+textfield_add 16 16 369 785
+textfield_delete 16 16 395 785
+textfield_key 16 16 421 785
+textfield_rename 16 16 447 785
+thumb_down 16 16 473 785
+thumb_up 16 16 499 785
+tick 16 16 525 785
+time 16 16 551 785
+time_add 16 16 577 785
+time_delete 16 16 603 785
+time_go 16 16 629 785
+timeline_marker 16 16 655 785
+transmit 16 16 681 785
+transmit_add 16 16 707 785
+transmit_blue 16 16 733 785
+transmit_delete 16 16 759 785
+transmit_edit 16 16 785 785
+transmit_error 16 16 811 5
+transmit_go 16 16 811 31
+tumblr 30 30 811 57
+tux 16 16 811 97
+twitter 30 30 811 123
+user 16 16 811 163
+user_add 16 16 811 189
+user_comment 16 16 811 215
+user_delete 16 16 811 241
+user_edit 16 16 811 267
+user_female 16 16 811 293
+user_go 16 16 811 319
+user_gray 16 16 813 345
+user_green 16 16 813 371
+user_orange 16 16 813 397
+user_red 16 16 825 423
+user_suit 16 16 825 449
+vcard 16 16 825 475
+vcard_add 16 16 811 501
+vcard_delete 16 16 811 527
+vcard_edit 16 16 811 553
+vector 16 16 811 579
+vector_add 16 16 811 605
+vector_delete 16 16 811 631
+wand 16 16 811 657
+weather_clouds 16 16 825 683
+weather_cloudy 16 16 825 709
+weather_lightning 16 16 825 735
+weather_rain 16 16 811 761
+weather_snow 16 16 811 787
+weather_sun 16 16 5 813
+webcam 16 16 31 813
+webcam_add 16 16 57 813
+webcam_delete 16 16 83 813
+webcam_error 16 16 109 813
+world 16 16 135 813
+world_add 16 16 161 813
+world_delete 16 16 187 813
+world_edit 16 16 213 813
+world_go 16 16 239 813
+world_link 16 16 265 813
+wrench 16 16 291 813
+wrench_orange 16 16 317 813
+xhtml 16 16 343 813
+xhtml_add 16 16 369 813
+xhtml_delete 16 16 395 813
+xhtml_go 16 16 421 813
+xhtml_valid 16 16 447 813
+zoom 16 16 473 813
+zoom_in 16 16 499 813
+zoom_out 16 16 525 813
diff --git a/engine/app.cpp b/engine/app.cpp
index dc21eb3..78ffd97 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -122,6 +122,9 @@ void App::init()
FontManager::init();
FontManager::load(kFont::Arial_11, ttf, 15);
FontManager::load(kFont::Arial_30, ttf, 30);
+ NodeBorder::static_init();
+ NodeImage::static_init();
+ NodeIcon::static_init();
layout.on_loaded = [&] {
layout[main_id].update(width, height);
@@ -136,9 +139,34 @@ void App::init()
msgbox->m_manager = &layout;
msgbox->init();
layout[main_id].add_child(msgbox);
- layout[main_id].update(width, height);
+ layout[main_id].update();
};
}
+ if (auto* button = layout[main_id].find("btn-settings"))
+ {
+ button->on_click = [this] {
+ settings = new NodeSettings();
+ settings->m_manager = &layout;
+ settings->init();
+ layout[main_id].add_child(settings);
+ layout[main_id].update();
+ };
+ }
+ if (auto* menu_file = layout[main_id].find("menu-file"))
+ {
+ menu_file->on_click = [=] {
+ glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
+ popup = (NodePopupMenu*)layout[const_hash("popup-menu")].m_children[0]->clone();
+ popup->SetPositioning(YGPositionTypeAbsolute);
+ popup->SetPosition(pos.x, pos.y);
+ layout[main_id].add_child(popup);
+ layout[main_id].update();
+ };
+ }
+ if (auto* toolbar = layout[main_id].find("toolbar"))
+ {
+ toolbar->m_flood_events = true;
+ }
};
layout.load("data/layout.xml");
@@ -152,8 +180,6 @@ void App::init()
ShaderManager::create(kShader::UVs, shader_v, shader_uv_f);
ShaderManager::create(kShader::Font, shader_font_v, shader_font_f);
ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f);
- NodeBorder::static_init();
- NodeImage::static_init();
if (!tex.load("data/uvs.jpg"))
printf("error loading image\n");
@@ -239,7 +265,6 @@ void App::mouse_down(int button, float x, float y)
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(x, y);
layout[main_id].add_child(popup);
- layout[main_id].update(width, height);
}
layout[main_id].update();
}
diff --git a/engine/app.h b/engine/app.h
index 5105c83..112961c 100644
--- a/engine/app.h
+++ b/engine/app.h
@@ -12,6 +12,7 @@ class App
Texture2D tex;
LayoutManager layout;
NodeMessageBox* msgbox;
+ NodeSettings* settings;
NodePopupMenu* popup = nullptr;
const uint16_t main_id = const_hash("main");
public:
diff --git a/engine/layout.cpp b/engine/layout.cpp
index f61cfde..80e197a 100644
--- a/engine/layout.cpp
+++ b/engine/layout.cpp
@@ -5,6 +5,7 @@
Plane NodeBorder::m_plane;
Plane NodeImage::m_plane;
Sampler NodeImage::m_sampler;
+std::map NodeIcon::m_icons;
kEventResult Node::on_event(Event* e)
{
@@ -164,9 +165,6 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
}
break;
case kAttribute::MinWidth:
- if (strchr(attr->Value(), '%'))
- YGNodeStyleSetMinWidthPercent(y_node, attr->FloatValue());
- else
YGNodeStyleSetMinWidth(y_node, attr->FloatValue());
break;
case kAttribute::MaxWidth:
@@ -313,6 +311,9 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
}
break;
}
+ case kAttribute::FloodEvents:
+ m_flood_events = attr->IntValue() > 0;
+ break;
default:
break;
}
@@ -355,6 +356,13 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
n->load_internal(x_child);
break;
}
+ case kWidget::Icon:
+ {
+ auto n = new NodeIcon();
+ add_child(n);
+ n->load_internal(x_child);
+ break;
+ }
case kWidget::Text:
{
auto n = new NodeText();
diff --git a/engine/layout.h b/engine/layout.h
index ef13d23..92a0b0e 100644
--- a/engine/layout.h
+++ b/engine/layout.h
@@ -8,8 +8,8 @@ enum class kAttribute : uint16_t
{
id = const_hash("id"),
Width = const_hash("width"),
- MinWidth = const_hash("max-width"),
- MaxWidth = const_hash("min-width"),
+ MinWidth = const_hash("min-width"),
+ MaxWidth = const_hash("max-width"),
Height = const_hash("height"),
MinHeight = const_hash("min-height"),
MaxHeight = const_hash("max-height"),
@@ -35,6 +35,8 @@ enum class kAttribute : uint16_t
Region = const_hash("region"),
Position = const_hash("position"),
Positioning = const_hash("positioning"),
+ FloodEvents = const_hash("flood-events"),
+ Icon = const_hash("icon"),
};
enum class kWidget : uint16_t
@@ -43,6 +45,7 @@ enum class kWidget : uint16_t
Shape = const_hash("shape"),
Text = const_hash("text"),
Image = const_hash("image"),
+ Icon = const_hash("icon"),
Button = const_hash("button"),
ButtonCustom = const_hash("button-custom"),
PopupMenu = const_hash("popup-menu"),
@@ -300,7 +303,7 @@ public:
glm::vec4 pad;
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
if (n == 1)
- m_color = glm::vec4(pad.x);
+ m_color = glm::vec4(pad.x, pad.x, pad.x, 1);
else
m_color = pad;
break;
@@ -628,7 +631,6 @@ public:
virtual void init() override
{
m_flood_events = true;
- SetPadding(10, 10, 10, 10);
SetPosition(0, 0);
SetWidth(100);
SetHeight(400);
@@ -658,8 +660,8 @@ public:
}
virtual void loaded() override
{
- m_thinkness = 1;
- m_border_color = glm::vec4(0, 0, 0, 1);
+ //m_thinkness = 1;
+ //m_border_color = glm::vec4(0, 0, 0, 1);
m_color = color_normal;
}
virtual kEventResult handle_event(Event* e) override
@@ -686,3 +688,77 @@ public:
return kEventResult::Consumed;
}
};
+
+class NodeSettings : public Node
+{
+ Node* m_template;
+ NodeButton* btnOk;
+public:
+ virtual Node* clone_instantiate() const override { return new NodeButtonCustom(); }
+ virtual void init() override
+ {
+ SetPosition(0, 0);
+ SetWidthP(100);
+ SetHeightP(100);
+ SetPositioning(YGPositionTypeAbsolute);
+ m_template = (*m_manager)[const_hash("settings")].m_children[0]->clone();
+ add_child(m_template);
+ btnOk = m_template->find("btn-ok");
+ btnOk->on_click = [&] { destroy(); };
+ }
+ virtual kEventResult handle_event(Event* e) override
+ {
+ return kEventResult::Consumed;
+ }
+};
+
+class NodeIcon : public NodeImage
+{
+ static std::map m_icons;
+ std::string m_icon_name;
+public:
+ static void static_init()
+ {
+ // spritesheet maker: https://draeton.github.io/stitches/
+ // icons: http://www.famfamfam.com/lab/icons/silk/
+ // regex css -> spritesheet.txt: \.([^{]+) {\s+width: (\d+)px;\s+height: (\d+)px;\s+.*: -(\d+)px -(\d+)px;\s+}\s+
+ // to: "\1",\2,\3,\4,\5\n
+ static char str[256];
+ int x, y, w, h;
+ FILE* f = fopen("data/spritesheet.txt", "r");
+ while (!feof(f) && fscanf(f, "%s %d %d %d %d", str, &w, &h, &x, &y) == 5)
+ {
+ m_icons[str] = glm::vec4(x, y, x+w, y+h);
+ }
+ fclose(f);
+ }
+ virtual Node* clone_instantiate() const override { return new NodeIcon(); }
+ virtual void clone_copy(Node* dest) const override
+ {
+ NodeImage::clone_copy(dest);
+ NodeIcon* n = static_cast(dest);
+ n->m_icon_name = m_icon_name;
+ }
+ virtual void create() override
+ {
+ m_region = m_icons[m_icon_name];
+ m_path = "data/spritesheet.png";
+ m_tex_id = const_hash(m_path.c_str());
+ m_use_atlas = true;
+ NodeImage::create();
+ auto tex_sz = TextureManager::get(m_tex_id).size();
+ YGNodeStyleSetAspectRatio(y_node, tex_sz.x / tex_sz.y);
+ }
+ virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
+ {
+ NodeImage::parse_attributes(ka, attr);
+ switch (ka)
+ {
+ case kAttribute::Icon:
+ m_icon_name = attr->Value();
+ break;
+ default:
+ break;
+ }
+ }
+};
diff --git a/engine/pch.h b/engine/pch.h
index 8531e49..ab8eb62 100644
--- a/engine/pch.h
+++ b/engine/pch.h
@@ -16,6 +16,7 @@
#include