diff --git a/SmoulderingBeachBall.sln b/SmoulderingBeachBall.sln
index d7de6b3..8328c68 100644
--- a/SmoulderingBeachBall.sln
+++ b/SmoulderingBeachBall.sln
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2016
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SmoulderingBeachBall", "SmoulderingBeachBall\SmoulderingBeachBall.fsproj", "{DFC3CBCA-3DA7-4CF4-A8BC-BCCB740FA6CD}"
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "SmoulderingBeachBall", "SmoulderingBeachBall\SmoulderingBeachBall.fsproj", "{DFC3CBCA-3DA7-4CF4-A8BC-BCCB740FA6CD}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SmoulderingBeachBallCLI", "SmoulderingBeachBallCLI\SmoulderingBeachBallCLI.fsproj", "{5C00D583-EF09-4FE6-A3FE-EB01454C0607}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{DFC3CBCA-3DA7-4CF4-A8BC-BCCB740FA6CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFC3CBCA-3DA7-4CF4-A8BC-BCCB740FA6CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DFC3CBCA-3DA7-4CF4-A8BC-BCCB740FA6CD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C00D583-EF09-4FE6-A3FE-EB01454C0607}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/SmoulderingBeachBall/InternalServices.fs b/SmoulderingBeachBall/InternalServices.fs
index ac0df8f..260e608 100644
--- a/SmoulderingBeachBall/InternalServices.fs
+++ b/SmoulderingBeachBall/InternalServices.fs
@@ -9,21 +9,30 @@
let validateDimension dimension =
match dimension with
| dimension when dimension <= 0 ->
- invalidArg "dimension" "The width and height must be greater than 0."
+ invalidArg "dimension" "[ERROR] The images height and width must be greater than 0."
| _ -> ()
let validateDirectory filePath =
let path = Path.GetDirectoryName filePath
match (Directory.Exists path) with
- | false -> invalidArg "filePath" "Unable to save to the specified location because it does not exist."
+ | false ->
+ invalidArg "filePath" "[ERROR] Unable to save to the specified location because it could not be found."
| true -> ()
module Drawing =
+ open System.Text
let penOffset penWidth = int (penWidth / (float32 2))
+ let setPenWidth imgWidth imgHeight =
+ let width = float32 imgWidth
+ let height = float32 imgHeight
+ if (width >= height) then
+ height * (float32 0.05)
+ else width * (float32 0.05)
+
let createBorderPath penWidth spec =
- let offset = penOffset penWidth
+ let offset = penOffset penWidth
[|Point (0, offset); // Essentially (0, 0)
Point ((spec.width - offset), offset);
Point ((spec.width - offset), (spec.height - offset));
@@ -47,11 +56,21 @@
let addOverlayToImage graphics spec =
let overlay = spec.overlay.Value
- let pen = new Pen (overlay.colour, Width = 10.0f)
+ let pen =
+ new Pen (overlay.colour, width = (setPenWidth spec.width spec.height))
match overlay.overlayType with
| Border -> drawBorder graphics pen spec
| Full -> drawFullOverlay graphics pen spec
+ let buildFileName spec =
+ let sb = new StringBuilder ()
+ sb.Append (spec.width.ToString ()) |> ignore
+ sb.Append "x" |> ignore
+ sb.Append (spec.height.ToString ()) |> ignore
+ sb.Append ".png" |> ignore
+ (sb.ToString ())
+
+
let drawImage spec =
let bitmap = new Bitmap (spec.width, spec.height)
let graphics = Graphics.FromImage (bitmap)
@@ -60,6 +79,6 @@
match spec.overlay.IsSome with
| true -> addOverlayToImage graphics spec
| false -> printfn "[INFO.] No overlay specified. Creating image without one."
- bitmap.Save (spec.filePath)
- bitmap.Dispose()
- graphics.Dispose()
\ No newline at end of file
+ bitmap.Save (Path.Combine (spec.filePath, (buildFileName spec)))
+ graphics.Dispose()
+ bitmap.Dispose()
\ No newline at end of file
diff --git a/SmoulderingBeachBallCLI/App.config b/SmoulderingBeachBallCLI/App.config
new file mode 100644
index 0000000..787dcbe
--- /dev/null
+++ b/SmoulderingBeachBallCLI/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SmoulderingBeachBallCLI/AppIcon.rc b/SmoulderingBeachBallCLI/AppIcon.rc
new file mode 100644
index 0000000..eb1ecab
--- /dev/null
+++ b/SmoulderingBeachBallCLI/AppIcon.rc
@@ -0,0 +1 @@
+1 ICON icon.ico
\ No newline at end of file
diff --git a/SmoulderingBeachBallCLI/AppIcon.res b/SmoulderingBeachBallCLI/AppIcon.res
new file mode 100644
index 0000000..1bd6c6c
Binary files /dev/null and b/SmoulderingBeachBallCLI/AppIcon.res differ
diff --git a/SmoulderingBeachBallCLI/AssemblyInfo.fs b/SmoulderingBeachBallCLI/AssemblyInfo.fs
new file mode 100644
index 0000000..1fedc7e
--- /dev/null
+++ b/SmoulderingBeachBallCLI/AssemblyInfo.fs
@@ -0,0 +1,41 @@
+namespace SmoulderingBeachBallCLI.AssemblyInfo
+
+open System.Reflection
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[]
+[]
+[]
+[]
+[]
+[]
+[]
+[]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// []
+[]
+[]
+
+do
+ ()
\ No newline at end of file
diff --git a/SmoulderingBeachBallCLI/ConsoleCommands.fs b/SmoulderingBeachBallCLI/ConsoleCommands.fs
new file mode 100644
index 0000000..9e47ed9
--- /dev/null
+++ b/SmoulderingBeachBallCLI/ConsoleCommands.fs
@@ -0,0 +1,114 @@
+namespace Commands
+
+ module ConsoleCommands =
+
+ open System
+ open Console.Waterworks
+ open Console.Waterworks.Attributes
+ open SmoulderingBeachBall.Services
+ open Validation
+ open System.IO
+
+ let showEndOfCommandMessage = "[INFO.] Execution completed."
+
+ []
+ []
+ []
+ []
+ let test () = "[SUCCESS] Smouldering Beach Ball CLI seems to be working."
+
+ []
+ []
+ []
+ []
+ let help () = CW_Liaison().RequestHelpDocumentation("Commands")
+
+ []
+ []
+ []
+ []
+ let cheat () =
+ try
+ printfn "[INFO] Attempting to save cheat sheet to the desktop..."
+ let cheatSheetPath = __SOURCE_DIRECTORY__ + "/cheat-sheet.pdf"
+ let savePath = getDesktopPath + "/smouldering-beach-ball-cheat-sheet.pdf"
+ File.Copy (cheatSheetPath, savePath, true)
+ showEndOfCommandMessage
+ with
+ | :? FileNotFoundException as ex -> ex.Message
+ | _ as ex -> ex.Message
+
+ []
+ []
+ []
+ []
+ let exit () = Environment.Exit (Environment.ExitCode)
+
+ []
+ []
+ []
+ []
+ let ``draw-default`` imgWidth imgHeight =
+ try
+ buildDefaultSpec imgWidth imgHeight
+ |> makeImage
+ |> Async.RunSynchronously
+ showEndOfCommandMessage
+ with
+ | :? ArgumentException as ex -> ex.Message
+ | _ as ex -> ex.Message
+
+ []
+ []
+ []
+ []
+ let ``draw-image`` imgWidth imgHeight mainColour oColour oType path =
+ try
+ buildSpec imgWidth imgHeight mainColour oColour oType path
+ |> makeImage
+ |> Async.RunSynchronously
+ showEndOfCommandMessage
+ with
+ | :? ArgumentException as ex -> ex.Message
+ | _ as ex -> ex.Message
+
+ []
+ []
+ []
+ []
+ let ``list-colours`` () =
+ printfn "[INFO.] Listing available colours..."
+ for item in colourList do
+ printfn "%s" item.Key
+ showEndOfCommandMessage
+
+ (* ALIASES
+ =======================================================================
+ These command-methods will not show up in the help section.
+ Before adding extra aliases, make sure the main version is as clear and
+ helpful to someone new to the program as possible. Aliases should be
+ treated as commands for experienced users and documented on the wiki,
+ hosted alongside the repository on GitHub.
+ URL: https://github.com/CraigOates/Smouldering-Beach-Ball/wiki *)
+
+ let dd imgWidth imgHeight =
+ ``draw-default`` imgWidth imgHeight
+
+ let di imgWidth imgHeight mainColour oColour oType path =
+ ``draw-image`` imgWidth imgHeight mainColour oColour oType path
+
+ let lc () = ``list-colours`` ()
diff --git a/SmoulderingBeachBallCLI/Program.fs b/SmoulderingBeachBallCLI/Program.fs
new file mode 100644
index 0000000..c43a2d1
--- /dev/null
+++ b/SmoulderingBeachBallCLI/Program.fs
@@ -0,0 +1,7 @@
+open Console.Waterworks
+
+[]
+let main argv =
+ let liaison = new CW_Liaison ()
+ liaison.Run ("Commands", true)
+ 0 // return an integer exit code
diff --git a/SmoulderingBeachBallCLI/SmoulderingBeachBallCLI.fsproj b/SmoulderingBeachBallCLI/SmoulderingBeachBallCLI.fsproj
new file mode 100644
index 0000000..9ff9e29
--- /dev/null
+++ b/SmoulderingBeachBallCLI/SmoulderingBeachBallCLI.fsproj
@@ -0,0 +1,96 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ 5c00d583-ef09-4fe6-a3fe-eb01454c0607
+ Exe
+ SmoulderingBeachBallCLI
+ SmoulderingBeachBallCLI
+ v4.7.1
+ true
+ true
+ SmoulderingBeachBallCLI
+ ..\SmoulderingBeachBallCLI\AppIcon.res
+
+
+ true
+ full
+ false
+ false
+ bin\$(Configuration)\
+ DEBUG;TRACE
+ 3
+ AnyCPU
+
+
+ false
+
+
+
+
+ pdbonly
+ true
+ true
+ bin\$(Configuration)\
+ TRACE
+ 3
+ AnyCPU
+
+
+ true
+
+
+ 11
+
+
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\Console.Waterworks.0.1.0.0-alpha1\lib\Console.Waterworks.dll
+
+
+ ..\packages\FSharp.Core.4.5.2\lib\net45\FSharp.Core.dll
+
+
+
+
+
+
+ ..\packages\System.Drawing.Common.4.5.0\lib\net461\System.Drawing.Common.dll
+
+
+
+ True
+
+
+
+
+ SmoulderingBeachBall
+ {dfc3cbca-3da7-4cf4-a8bc-bccb740fa6cd}
+ True
+
+
+
+
\ No newline at end of file
diff --git a/SmoulderingBeachBallCLI/Validation.fs b/SmoulderingBeachBallCLI/Validation.fs
new file mode 100644
index 0000000..3820173
--- /dev/null
+++ b/SmoulderingBeachBallCLI/Validation.fs
@@ -0,0 +1,85 @@
+module internal Validation
+
+ open System.Drawing
+ open SmoulderingBeachBall.Domain.DomainTypes
+ open System
+
+ let colourList =
+ [ "blue", Brushes.AliceBlue;
+ "brown", Brushes.Brown;
+ "black", Brushes.Black;
+ "gray", Brushes.Gray;
+ "green", Brushes.Green;
+ "purple", Brushes.Purple;
+ "red", Brushes.Red;
+ "white", Brushes.White;
+ "yellow", Brushes.Yellow;]
+ |> Map.ofList
+
+ let isColourValid (colour: string) =
+ colourList
+ |> Map.containsKey (colour.ToLower())
+
+ let parseColour colour =
+ match (isColourValid colour) with
+ | true ->
+ colourList
+ |> Map.find (colour.ToLower())
+ | false ->
+ invalidArg "Colour"
+ (String.Concat("[ERROR] The colour specifed is invalid.\n",
+ "Please use the 'list-colours' command to see what you can use."))
+
+ let getDesktopPath =
+ Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+
+ let parsePath (path: string) =
+ match path with
+ | path when ((path.ToLower()).Equals "desktop") -> getDesktopPath
+ | path when ((path.ToLower()).Equals "d") -> getDesktopPath
+ | _ -> path
+
+ let buildDefaultSpec iWidth iHeight =
+ let oSpec =
+ { colour = Brushes.Black
+ overlayType = Full }
+ let spec =
+ { width = iWidth
+ height = iHeight
+ colour = Brushes.AntiqueWhite
+ filePath = getDesktopPath
+ overlay = Some oSpec
+ }
+ spec
+
+ let parseOverlay (oType: string) =
+ match oType.ToLower() with
+ | "border" -> Border
+ | "b" -> Border
+ | "full" -> Full
+ | "f" -> Full
+ | _ -> invalidArg "Overlay Type" "The overlay type must be either 'border' or 'full'."
+
+ let buildOverlaySpec oColour (oType: string) =
+ let oSpec =
+ { colour = parseColour oColour;
+ overlayType = parseOverlay oType }
+ oSpec
+
+ let buildMainSpec iWidth iHeight mainColour path oSpec =
+ let spec =
+ { width = iWidth;
+ height = iHeight;
+ colour = parseColour mainColour
+ filePath = parsePath path
+ overlay = oSpec }
+ spec
+
+ let buildSpec iWidth iHeight mainColour oColour (oType: string) path =
+ let spec =
+ match oType.ToLower() with
+ | "none" | "n" -> buildMainSpec iWidth iHeight mainColour path option.None
+ | _ ->
+ let oSpec = buildOverlaySpec oColour oType
+ buildMainSpec iWidth iHeight mainColour path (Some oSpec)
+ spec
diff --git a/SmoulderingBeachBallCLI/cheat-sheet.pdf b/SmoulderingBeachBallCLI/cheat-sheet.pdf
new file mode 100644
index 0000000..379d99b
Binary files /dev/null and b/SmoulderingBeachBallCLI/cheat-sheet.pdf differ
diff --git a/SmoulderingBeachBallCLI/icon.ico b/SmoulderingBeachBallCLI/icon.ico
new file mode 100644
index 0000000..5d6956f
Binary files /dev/null and b/SmoulderingBeachBallCLI/icon.ico differ
diff --git a/SmoulderingBeachBallCLI/packages.config b/SmoulderingBeachBallCLI/packages.config
new file mode 100644
index 0000000..45c38e7
--- /dev/null
+++ b/SmoulderingBeachBallCLI/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file