My current progress w.r.t. quitting smoking…

So far…

Image may contain: text that says "My daily no more smoking share... (2020/12/11) 0 years, 1 month, 21 days Meth (2013/09/01) 7 years, 5 months, 1 day"

I still share it most days on Facebook, but I’m not going to do so every day here because the image space is limited on WordPress. I am sharing it occasionally though, because last time my attempt at quitting smoking was a dismal failure. This time it’s going well.

I added the meth recovery details onto the app a while back (because my cigarette smoking clean time is not terribly impressive really, haha), and just today added the option to add the formatted start date for each to the image it generates.

But anyway, I’m sharing this as a reminder that quitting smoking is not impossible after all. I used to think it was.

So far, so good…

I’ve improved my app a little bit, and now the image generated looks like this:

image

Actually I waited for one month before changing the format, because 0 years, 0 months, N days of being free from cigarettes would look depressing. Also including the meth recovery time makes it more impressive.

Not sharing the full code this time as it isn’t really much, but I do like this hacky method I found (here) to format the time span nicely. Timespans in .Net don’t do years and months by default, but this code uses a clever little trick of starting not with the actual start date, but with a date time of year, month, and day of 1. Actually if you go to the linked StackOverflow question, you’ll see I changed it from the one on the linked page – theirs was off by one day.

private string FormatDifference(DateTime startDate, DateTime endDate)
{
    DateTime zeroTime = new DateTime(1, 1, 1);
    DateTime curdate = DateTime.Now.ToLocalTime();
    TimeSpan span = curdate - startDate;

    // because we start at year 1 for the Gregorian 
    // calendar, we must subtract a year here.
    int years = (zeroTime + span).Year - 1;
    int months = (zeroTime + span).Month - 1;
    int days = (zeroTime + span).Day - 1;
    return string.Format("{0} years, {1} months, {2} days", years, months, days);
}

I may still make the application more generic and useful to others, then release it, but haven’t done so yet. This one has 2 start dates that are persisted and then it uses the method above to work out the formatted time between those 2 start dates and the current date, then replaces tokens in a format string.

A “proper” application to do this would allow you to add as many addictions as you would like to list, with a configurable start date and label for each… but I don’t really have the time and wrote this in a couple of minutes.

A simple app I’m using to share the number of days since I quit smoking cigarettes

This is something of a conundrum for me… It’s getting annoying to work out how many days have passed since I quit smoking, but I also want to share it on Facebook every day, as I have been. The conundrum is: I’m lazy, but to avoid having to look at a calendar every day, and this is only going to get worse, I must do some work.

So here it is, a silly little application to work it out and allow me to copy an image to the clipboard before sharing. It looks like this:

SNAGHTML2a830a49

It’s quite crude, and calculates the size of the font to be used by dynamically measuring text programmatically in a loop before doing the actual drawing, onto an image I created by drawing a gradient. So an obvious limitation is that the first line won’t be cantered… because I measure the text using a rectangle, and when I have tried centering the text it fucks it up completely, and I am after all lazy.

I could probably also allow choosing the gradient start and end colours, or maybe allow the user to load an image instead.

But still, I like it. The shadow is achieved simply by drawing twice… i.e. calculate where to draw, and then draw once with x+5, y+5, in black, and then draw again at the proper X and Y coordinate, in white… I draw the shadow first because I’m drawing directly onto the bitmap, so drawing the white first would land up with the black drawing over it.

For anyone interested, the source code is pretty elementary… main form is this:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SmokeFree
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            Clipboard.SetImage(pictureBox1.Image);
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshText();
        }

        private void dtStart_ValueChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.StartDate = dtStart.Value;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Properties.Settings.Default.Save();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dtStart.Value = Properties.Settings.Default.StartDate;

            var lines = new List<string>();

            foreach (var line in Properties.Settings.Default.Template)
            {
                lines.Add(line);
            }

            richTextBox1.Lines = lines.ToArray();

            RefreshText();
        }

        private void RefreshText()
        {
            var days = DateTime.Today.Subtract(dtStart.Value).Days.ToString();
            pictureBox1.Image = ImageUtilities.ModifyImage(ImageUtilities.OutputGradientImage(), richTextBox1.Text.Replace("[N]", days));
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            var lines = new System.Collections.Specialized.StringCollection();
            lines.AddRange(richTextBox1.Lines);
            Properties.Settings.Default.Template = lines;
        }
    }
}

And the code that plays with the images is this:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace SmokeFree
{
    internal class ImageUtilities
    {
        public static Image ModifyImage(Image image, string text)
        {
            bool indexPixelFormat = image.PixelFormat == PixelFormat.Format8bppIndexed;

            // if indexPixelFormat, this must be explicitly disposed.
            Image tempImage = indexPixelFormat ? new Bitmap(image.Width, image.Height) : image;

            try
            {
                using (Graphics graphics = Graphics.FromImage(tempImage))
                {
                    if (indexPixelFormat)
                        graphics.DrawImage(image, 0, 0);

                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                    float fontSize = 100;
                    Font font = new Font("Segoe UI Emoji", fontSize, FontStyle.Bold);
                    try
                    {
                        // Measure string to figure out the width needed, starting with font size 100 loop down until it will fit.
                        SizeF stringSize = graphics.MeasureString(text, font);

                        while (stringSize.Width > image.Width || stringSize.Height > image.Height)
                        {
                            font.Dispose();

                            fontSize -= 2;
                            font = new Font("Segoe UI Emoji", fontSize, FontStyle.Bold);
                            stringSize = graphics.MeasureString(text, font);
                        }

                        /* Draw twice, first in transparent black and then
                         * transparent white, so we have a shadow effect. */
                        using (SolidBrush shadowBrush = new SolidBrush(Color.FromArgb(255, 0, 0, 0)),
                            textBrush = new SolidBrush(Color.FromArgb(255, 255, 255, 255)))
                        {
                            float x = (image.Width - stringSize.Width) / 2F;
                            float y = (image.Height - stringSize.Height) / 2F;

                            graphics.DrawString(text, font, shadowBrush, new PointF(x + 5, y + 5));
                            graphics.DrawString(text, font, textBrush, new PointF(x, y));
                        }
                    }
                    finally
                    {
                        font.Dispose();
                    }
                }
            }
            finally
            {
                if (indexPixelFormat)
                    tempImage.Dispose();
            }

            return image;
        }

        public static Bitmap OutputGradientImage()
        {
            Bitmap bitmap = new Bitmap(640, 480);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, 640, 480), Color.Blue, Color.Red, LinearGradientMode.Vertical))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, 640, 480));
                return bitmap;
            }
        }
    }
}

I’m in Limbo

Last night in my nightmares, I couldn’t breathe properly. I shifted awkwardly between asleep and awake, laying thinking of one memory in particular that haunts me – my mother on that Tuesday night before I dropped her at the hospital on Wednesday morning; my mother sitting at the dining room table after walking from her bedroom to the lounge, just a few meters being enough to leave her out of breath, sitting there panting with her head in her hands. I laid there thinking that, and then shifting back to sleep where I dreamed that I was the one struggling to breathe. Then I woke confused, uncertain if this was a dream or if I really did struggle.

I’ve started wondering if this was really a sensible time to quit cigarettes. My last smoke was quite late on Thursday night, but the craving has been quite intense since then. But it’s not just craving – I’m angry. This anger flares up in response to tiny things that should be insignificant. I don’t remember ever craving meth like this, but I am craving a cigarette. The part of me that wants it begs and pleads, insisting that all I need is one; that I can bum from my neighbour, Mervin downstairs, who normally bums from me. But no! I shut those thoughts down each time, by playing back that mental image of my mother, sitting there with her head in her hands as she struggled to breathe. I hear her voice, as she called me on her last day, a week ago yesterday, to tell me that they would try to drain the fluid from her lung using a needle. I thought I’d see her later that day. They were supposed to help her, not suddenly kill her! That’s why I’m still in shock. And I think of how she died not two hours later, but also that she might have lived much longer if she’d quit smoking sooner. I need to quit and not give in to any cravings, so that I can live longer, for my son.

So I have motivation, but it’s hurting. The more I think about it, the more it hurts.The grief and sense of loss is otherwise not as bad as it was a week ago. It’s still bad, but it’s OK. But the not smoking thing is really fucking me up. Even my sense of the passing of time is different without nicotine. I don’t know how that can be, but some annoying tasks, such as pulling off from a traffic light… seem to take much longer now. The waiting for the lights to change from red to green… seems much longer than it needs to be. I used to take a lot of smoke breaks as well, sometimes before and after doing just about every little thing. Now I have all this extra time and no clue what to do with it.