I've done this recently...
I'm using a PIC24 (this is my first microcontroller project, so don't take this as gospel).
I have a main processing loop that checks for "flags" and does something when a flag is set, e.g. update display. The main processing loop is a never ending while loop. I set flags and do minimal processing from the interrupts. Some of my flags include display update, sleep commands, anything to do with peripherals, etc.
My button processing is done in a 1ms interrupt, it does the debounce and any menu routines that I have to update . These routines are very short/fast. These routines then set the "display flag" for the main processing routine.
I'm currently using three timers, one for a wait routine (it's separate because I need it enabled before the others), one at 1 second for longer delay items and one at 1ms for button processing. I keep counters to keep track of what needs to be done when. For example, my device sleeps after three minutes of no button presses. I increment a counter in the 1 second timer, when it reaches 180, I set the processing flag for the sleep command. When the interrupt exits, it goes back to the main processing routine which checks for that flag -- if set, it sleeps.
Brad