0

I'm trying to design a menu interface on a 1.8'' TFT display module. I've got it working with the Adafruit_ST7735 + Adafruit_GFX libraries. At least when I was just trying out the features... But now I'm trying to organize the code in Classes as this thing will get too complex soon. I have done some Java and C, so I started learning C++. I've been reading and coding nonstop for a week now, but there are some things that I can't wrap my head around that keep me from making any progress for a couple of days already.

So... For example there's a function public void drawRect(); in Adafruit_ST7735 library and I have a function draw() that draws a bunch of related stuff to the display in my own class (Rectangle.cpp). Say I initialize the display in my main program file how can I use that drawRect() function in my Rectangle::draw()?

Also Rectangle will be used for composing other parts of the menu interface and will probably be initialized in a collection or as a member of another class.

I've tried a bunch of different things but I've come to a dead end.

EDIT:

main program:

#include "_v0_0_0.h"
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#include "Point.h"
#include "Rectangle.h"
#include "SomeView.h"

#define     TFT_CS  4
#define     TFT_RST 0
#define     TFT_DC  10

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
SomeView a_view;

void setup()
{
    tft.initR(INITR_BLACKTAB); // initializes the display
}

void loop()
{
    a_view.draw(); //draw something to view (a button, scrollbar, menu item, etc)
    while (true) {}
}

SomeView.h:

#include "Rectangle.h"

class SomeView {
private:
    Rectangle a_rectangle;
public:
    SomeView();
    void draw();

    const Rectangle& getRectangle() const {
        return a_rectangle;
    }

    void setRectangle(const Rectangle& rectangle) {
        a_rectangle = rectangle;
    }
};

SomeView.cpp:

#include "SomeView.h"

SomeView::SomeView() :
        a_rectangle(Point::Point(0, 0), Point::Point(0, 0)) {
}

void SomeView::draw() {
    a_rectangle.setCorners(Point::Point(0, 0), Point::Point(2, 6));
    a_rectangle.draw();

    a_rectangle.setCorners(Point::Point(20, 66), Point::Point(100, 100));
    a_rectangle.draw();
}

Rectangle.h:

#include "Point.h"
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

class Rectangle{
private:
    Point p1;
    Point p2;
public:
    Rectangle();
    Rectangle(Point& p1, Point& p2);
    void setCorners(const Point& p1, const Point& p2);
    void draw();

    // ... getters and setters for the points
};

Rectangle.cpp:

#include "Rectangle.h"

Rectangle::Rectangle() : p1(), p2()
    {
    }

Rectangle::Rectangle(Point& p1, Point& p2) : p1(p1), p2(p2)
    {
    }

void Rectangle::setCorners(const Point& p1, const Point& p2) {
    this->p1 = p1;
    this->p2 = p2;
}

// this is where I want to use a function from the adafruit library
void Rectangle::draw() {
    Adafruit_ST7735::drawRect(p1.getX(), p1.getY(), p2.getX(), p2.getY(), ST7735_GREEN); 

}
1
  • So are you asking how to pass the tft to a class after creating this object ?.... Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); Oct 28, 2015 at 20:57

2 Answers 2

0

There are two basic methods to do what you want:

  1. Inheritance
  2. Pointer passing

Inheritance involves making your new class a child class of the Adafruit TFT class. You new class then gets all the public functions of the Adafruit class - it essentially becomes the Adafruit class plus your extra functions overlaid over the top:

class Rectangle : public Adafruit_ST7735 {
    ...
};

You have to ensure that you provide a suitable constructor that passes the right parameters to the Adafruit parent class, and then you create a Rectangle class instead of the Adafruit class in your sketch.

That is fine if you just want one class that uses the functions from the Adafruit class. The second option is to pass a pointer (or reference) to the Adafruit class to your other classes, either when you construct them or at function call time. For instance, you might have:

class Rectangle {
    private:
        Adafruit_ST7735 *_tft;

    public:
        Rectangle(Adafruit_ST7735 &tft) : _tft(&tft) {}
};

Then in your function you can use:

void Rectangle::draw() {
    _tft->drawRect(p1.getX(), p1.getY(), p2.getX(), p2.getY(), ST7735_GREEN);
}

You would, of course, construct your class with:

Adafruit_ST7735 myTFTScreen(blah blah blah);
Rectangle myRect(myTFTScreen);

Then call myRect.draw();.

0

Yes, there is a way.

However that's not how object oriented programming (OOP) is supposed to be used, at least in theory.

Most likely you won't like my advice, but here it is: take it easy, find a good book or online course and learn to program on a system that is simpler to debug, than a microcontroller.

Your PC, for example.

C is closer to the HW than java. C++ can be seen as both of them, but there is not so much you can do without learning C, properly. From that perspective, C++ can be seen also as a superset of C, only much more complex.

Have a look at this explanation, for example. It's quite simple, but exhaustive. Read it carefully and you will find out that pointers are not so difficult to grasp, after all.

If you spend enough time to get the basics right, it will save you lots of frustration (and, yes, time!) later on.

For a more systematic approach, try this.

8
  • Thank you for your advice! Though this was the kind of answer I was afraid I'm going to get. It's not that I'm not willing to learn. I've read most of the material on [link]learncpp.com but it's like with learning... a new language :D In the beginning you start to grasp the meaning of single words or expressions but it's hard to form a meaningful text - there will be lots of grammar mistakes and cases of misused words. So I understand what you we're saying but you're also suggesting that I should put this project aside. That won't happen.
    – Peeter3000
    Oct 28, 2015 at 20:00
  • Sure, it's your time after all and a lesson is not fully learned till one has paid the price for it. But you know the saying: the wise man learns from own mistakes, while the smart one learns from others' ;-) Oct 28, 2015 at 20:02
  • More to the point of the question you asked: you got my answer because you question is too generic and doesn't show exactly what you are trying to do, why, how and what error you get. Lacking that, you get the rubber stamp answer. Oct 28, 2015 at 20:05
  • I thought my question was descriptive enough (though a bit emotional while still trying the best to express myself) but I didn't provide any concrete examples of what I have been doing because my last experiments have become so desperate and ridiculous that these won't have any descriptive value to my problem. I tried to keep it generic also to strip away details which I thought of as being trivial. Also I feel like none of your answers have been more on point than my question.
    – Peeter3000
    Oct 28, 2015 at 20:24
  • Indeed. That's what you get for not being clear/precise enough. How do you think that the answer could be more precise than the question? If I had a working crystal ball, I'd be hitting a different type of website. The type specialized in trading stocks. Oct 28, 2015 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.