REBOL [
	Title:	"Sticky Notes"
	Date:	10-Dec-2008
	File:	%sticky-notes.r
	Purpose: {Simple but useful sticky note application.
	Click on New to create new note item.
	Use icons on note items to edit, delete & resize the item.
	Click on an item to move, hold CTRL to align.
	All notes will be saved (compressed) under %notes.dat when you
	click on Save or Quit.
	}
	Version: 1.0.0
	Author: "Endo"

	Library: [
		level: 'intermediate
		platform: none
		type: 'tool
		domain: [user-interface vid]
		tested-under: 'windows
		license: none
		see-also: none
	]
]

delete-img: make image! [16x16 #{
000000000000000000000000000000000000000000000000000000000000
4A06065D0F10250C0C0603030000000000000000000000000000004A0C0C
7F28284521210B0707000000000000480202A01918B74D4C6D3837211010
060404000000000000000000490605A61816CF5B589158572517170C0202
4702029F1312D65A55F1A499D76F60852C233115140E0A0A000000350302
9A100BD93524F58F7DDF9990744644371010901312D6514AF5917FFE8769
FA603DDD39229229253A1E1E00000033010190120AE4472CFE7D5DFB9E8A
CD857E844645C05C56F48C78FE876AFB7556EB4B34CE1B109713123B1414
0000000C00003306049C3024EE6D54FE8263F89F8CE49C93F2927FFD7F60
F77358E24939C216108B02023F02020D02020000000000000800003A0907
A73325F15433FE5E38FE6A49FD5C37F25336D93225B10C09700101290000
0600000000000000000000000000003701007A0E07DB381BFE5027FF5228
F94924DC3121A41211540101180000020000000000000000000000000000
460101980804C72615F05D3FFA7D62FB8267FA6A4AE1442E812C28180909
0101010000000000000000000000004801019F0905D42515F25539F16751
DD473CDF5547F6775EF55838BD41324825230A0808000000000000000000
4901019E0907D5291CEE5239E7513FCB261F9B08077F110EC54A3DF5684D
ED4E32A33D34321D1D040404000000000000600202B81E18E65141DF4336
BC17137D03023300001801015C130FC84A3DF3654CE14F3B883A35221616
0403030000002F01017F1410C62823AA0E0C6201011F0000040000020000
160101661512CD5145EF6855CE473D69302F110C0C0100000C0000300101
5A02023F00001100000100000000000000000300001C0201711A16CB4139
CE2B268C29291E0F0F000000000000050000070000040000000000000000
0000000000000000000600002402026F08088505053F0707090303000000
000000000000000000000000000000000000000000000000000000000000
0900001E0000210000080000000000000000
} #{
FFFFFFFFFFFFFFFFFFFF
FCECF3FFFFFFFFFFFFFD
EAE8FCFFFFFCD2859BE1
FDFFFFFFFBD47977D6FD
FCD163162170CCF6FFFC
CE6115187BE0CF631201
011155B9FFF6971D0102
25785A11010000042A8F
FFFCC9530B0004120B01
0001082C7CCCFFFFF8BE
4808000000000211459A
DFFAFFFFFFF192190000
00021B62B8EEFEFFFFFF
FBCC5A0C0000000648C1
F6FFFFFFFFFBCB5D1001
020502022CA6F5FFFFFF
FBCD5C10010622452304
0748C2FAFFFFE7791202
0C398CC58D25030E62D7
FEFFED84181954AAE7FB
E68720031982E9FFFDD0
7C84C7F3FFFFFEE27C1B
0744C8FCFFFBECEDFBFF
FFFFFFFEDC784082DEFE
FFFFFFFFFFFFFFFFFFFF
FCDAB6DAFAFF
}]

edit-img: make image! [16x16 #{
000000000000000000000000010101070707090A09080908050605030302
000000000000000000000000000000000000000000000000000000000000
0C0D0D3E43414F55534B514D404641333834292C291F221F161815090A09
0101010000000000000000000000000202022E3334949E9EA4AFAF9AA6A5
8F9C9983908E7C898674807C67716B3F453D0C0C0A000000000000000000
0000000F1212747E80D7E2E4DBE7E9CFDEE1BED1D5AAC3C898B7BD8BADB3
83A4A86D7C77201F19010100000000000000030404394244B4C4C7E1F0F3
E1F1F5DBEEF2CFE8EEBDDFE6A6D3DD92C8D48EC0CB82939029261E020101
000000000000131819758A8ECAE1E6D4EBF0CDE8EEC8E5ECC0E2E9B2DBE4
9FD2DD8FCAD79FCAD49199932D281D020201000000040606394B4F99BEC5
B9DEE6C1E2E9BEE1E8B3DBE4A9D6E09FD2DD92CCD88FC8D5B1D1D894988F
302A1D030201010101141F215F899292CAD5A0D2DDA9D7E1AAD7E1A3D4DE
97CEDA8CC8D585C4D299CBD6C0D5DA92948B332C1D040301060B0C2C5057
62AAB974BECE85C6D495CDD993CCD88FCAD688C6D37FC2D082C1CFADD3DB
C4D4D78D8E83372E1C050401122C32317C8C44A5B94FACBF6DB9C981C2D0
80C1D07CC0CE79BECC78BDCB8FC5D1BFD9DFC0CDD08787793A301B060502
2466742790A62696AE309AB158ACBE6BB5C56CB5C56BB5C56AB5C575B8C7
A4CCD5C5D9DFB8C4C6827F6E3F331C080603337685348EA13096AC399DB3
55AABD5CACBE5BABBD5BAABC5EABBD7FB9C6B6D1D8C4D6DBAEB9BA7F7A65
483A1F0B0804101F2219333928515A558C9773B1BE6DB3C363B0C15BACBD
61ACBD96C1CBBED3D8C0D0D5A3AEAE7C755E4E40230D0A05000000010202
080A0B2F36385966696F868B7A9EA57BABB688B7C1AFC9D0BED1D6BBC9CC
919C9C5956483028180806030000000000000000000303030A0A0A171818
2B2E2F454C4D656E70899294A2ACAF9CA5A65960611A1C1B060503010100
0000000000000000000000000000000000000101010505050F0F0F212222
3C3E3E3F4141161717020303000000000000
} #{
FFFFFFFFFFF9F6FAFDFF
FFFFFFFFFFFFFFFFFFFF
F5B997A6B8C8D6E3EEF9
FFFFFFFFFFFECD4C191E
2936465974B0F0FFFFFF
FFF08614010101020406
0E3FC8FEFFFFFDC44208
0000000000000020B4FD
FFFFEB84280700000000
0000001BABFCFFFBBF58
2B080000000000000016
A2FBFFE68B5031070000
00000000001299F9F7BC
6F5B3305000000000000
000F8FF7D8906B612D03
000000000000000C85F4
996B65591F0100000000
0000000A7BF17F635940
0F000000000000000008
70EDDCC5A25110030100
00000000000866E5FFFE
F3BC7B502E1609030001
0C3E97ECFFFFFFFCF2E0
C39D724929245CBAEEFE
FFFFFFFFFFFFFEF9EBD2
AEA2D4F8FFFF
}]

resize-img: make image! [16x16 #{
0000000000000000000000000000000000000000000E380E143714060C06
000000000000000000000000000000000000000000000000000000000000
0000000000000000000E660D2A77271A2D19060806000000000000000000
000000000000000000000000000000000000000000000000041F04156F11
66BA5B5D905621361F0A0D0A000000000000000000000000000000042704
0D480C1446141848171A4F181F631C338E2CA1DC92AEE29E5A9A4C294426
0E130E020302000000000000000000074B062B992466B05D82BA7D88C284
89C78390D184BDEEAAC1F2A991DD7458A1472B4C280B100B010101000000
0000000A610747B2319CDD80C3ECB0C7EEB5C2EFADB1EC959DE8779AE773
9DE67980D55D56A4422A4E260D120D04040401210012770C50BB3074D145
81D85484DC5782DD557CDC4C76DB4477D9457FD95379D54C6FCD4754A83F
2C582917221703360220871461C43B72D04373D24474D34472D4426FD33D
6DD23A71D2407DD55281D55675D14C4FBD352C9126234823054D03369B26
83D4619CDE7A9DDE7C9BDE7993DB6F84D65A7BD34E8BD8649DDE7C8CD76C
51BD3918970F085D07092109076F053DA82D7FD26590D87995DA7E98DB80
9BDC80A3E085A2E083A4E0858BD76E4BBA37138E0C014F01001600000200
0262010F680B1F8018248B1E2991212F972447AD3692D877AAE48E86D56A
40B42E0E8609014300001000000100000000001400001100001900001D00
012000023101277D1E8BD77182D66937B0280A7D06013800000B00000100
000000000000000000000000000000000000000300022D012F8F2269CB53
32AB25077204003000000800000000000000000000000000000000000000
000000000000000000023F011994111FA016066804002500000500000000
000000000000000000000000000000000000000000000000000000002C00
026602025801001D00000300000000000000000000000000000000000000
000000000000000000000000000000000D00001B00001200000200000000
000000000000000000000000000000000000
} #{
FFFFFFFFFFFFFFFCF5FC
FFFFFFFFFFFFFFFFFFFF
FFFFFFE4A5CFF9FFFFFF
FFFFFFFFFFFFFFFFFEC4
3E57C0F6FFFFFFFFFFFF
F4E7DED9D1901C0C49B3
F3FFFFFFFFF3A6635046
3B240600093DA6EFFFFF
FFDC5109040201010000
00063299E9FEFDC12E01
00000000000000000429
8CDDF79B170000000000
0000000000042B8EEB73
0A000000000000000000
010E47A1D65105010000
0000000000011353B1EA
E0793628211A0C010000
021961BFF3FFFBE1C3B5
AA97490600042170CBF7
FFFFFFFFFEFCFAE66807
062B81D5F9FFFFFFFFFF
FFFFFFE1560D3692DFFC
FFFFFFFFFFFFFFFFFFE6
734FA1E7FDFFFFFFFFFF
FFFFFFFFFFF9CEBFEAFE
FFFFFFFFFFFF
}]

random/seed now

base-face: make face [
	size: 200x80
	offset: 100x100
	text: "New Note"
	color: white
	edge: make edge [size: 1x1 color: black]
	effect: [gradient 0x1]
	indent: 3x2
	data: true	;means this is a notes item
	font: make font [
		name: "Verdana"
		size: 12
		style: [bold]
		color: white
		align: 'left
		valign: 'top
		space: 0x0
		shadow: 1x1
	]
]

;I took this function from %chess-board.r
move-to-end: func [series item /local item-index item-value] [
	item-index: find series item
	item-value: first item-index
	remove item-index
	append series item-value
	show last series
	show item-value
]

button-face: make face [
	size: 16x16
	color: none
	edge: none
]

drag-feel: make face/feel [
	engage: func [f a e] [
		if find [down] a [move-to-end main-window/pane f data: e/offset mode: 'move]
		if find [alt-down] a [move-to-end main-window/pane f data: e/offset - f/para/scroll mode: 'scroll]
		if find [over away] a [
			if/else mode = 'move [
				f/offset: f/offset + e/offset - data
				if e/control [ ;snap to grid
					f/offset: (f/offset / 10) * 10
				]
			] [
				f/para/scroll: to-pair reduce [0 second e/offset - data]
			]
			show f
		]
	]
]

delete-feel: make face/feel [
	engage: func [f a e] [
		if a = 'down [
			if request/confirm "Delete Item?" [
				remove find main-window/pane f/parent-face
				show main-window
			]
		]
	]
]

resize-feel: make face/feel [
	engage: func [f a e] [
		if find [down alt-down] a [data: e/offset]
		if find [over away] a [
			old-size: f/parent-face/size
			f/parent-face/size: f/parent-face/size + e/offset - data
			if any [f/parent-face/size/x < 60 f/parent-face/size/y < 40] [
				f/parent-face/size: old-size
			]
			data: e/offset
			f/parent-face/line-list: none	;if you remove this word wrap won't work if text length > 200 
			show f/parent-face
		]
	]
]

edit-feel: make face/feel [
	engage: func [f a e] [
		if a = 'down [
			edit-area/text: copy f/parent-face/text
			inform/offset/title edit-window (main-window/offset + f/parent-face/offset + 30x50) "Enter Note"
			if edit-area/text <> "_cancel_" [
				f/parent-face/text: copy edit-area/text
				f/parent-face/line-list: none
				show f/parent-face
				save-note-list
			]
		]
	]
]

add-new-item: func [item [block!]] [
	append main-window/pane make base-face [
		feel: drag-feel offset: item/1 size: item/2 color: item/3 text: item/4
		para: make para [
			origin: 2x16
			;indent: 10x10
			wrap?: on
		]
		pane: reduce [
			;delete button
			make button-face [
				image: delete-img
				offset: 0x0
				feel: delete-feel
			]
			;edit button
			make button-face [
				image: edit-img
				offset: 16x0
				feel: edit-feel
			]
			;resize button
			make button-face [
				image: resize-img
				offset: 32x0
				feel: resize-feel
			]
		]
	]
]

load-note-list: does [
	foreach item items [
		add-new-item to-block item
	]
]

save-note-list: has [f] [
	items: copy []
	foreach f main-window/pane [
		if f/data [
			append/only items reduce [f/offset f/size f/color f/text]
		]
	]
	save %notes.dat compress mold items
	;save %notes.dat items	;uncompressed file
]

edit-window: layout [
	backcolor 120.140.120
	backeffect [grid 110.130.110]
	edit-area: area wrap copy ""
	across
	button "OK" [hide-popup]
	button "Cancel" [edit-area/text: copy "_cancel_" hide-popup]
]

main-window: layout [
	size 800x600
	backcolor 100.120.100
	backeffect [grid 10x10 110.130.110]
	across
	button "New"    [add-new-item reduce [100x100 200x80 random 255.255.255 "New Note"] show main-window]
	button "Save"   [save-note-list]
	button "Quit"   [save-note-list quit]
]

if items: attempt [load decompress load %notes.dat] [load-note-list]
;if items: attempt [load %notes.dat] [load-note-list]	;load from uncompressed file

view main-window